﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Drawing.Drawing2D;
using System.Text.RegularExpressions;

namespace FeiYang
{
    public enum 任务名_
    {
        无_,
        启动模拟器_,
        启动游戏_,
        登陆游戏_,
        重启模拟器_,
        小退后登陆_,
        初始设置_,
        正式开始挂机_,
        判断游戏状态_,
        去挂机地图_,
        已经到达挂机地图_,
        监控挂机状态_,

        军机令任务_,
        押镖任务_,
        声望任务_,
        王城任务_,
        骑兵任务_,
        挖矿任务_,
        论武任务_,
        领取奖励_,
        完成声望任务_,
        完成当前王城任务_,
        完成拉镖任务_,
        去海岛打开押镖礼盒_,
        去海岛等待镖车_,
        完成所有王城任务_,

        去沙城买药_,
        海岛存药_,
        结束买药存药_,
        沙城仓库扔药_,
        沙城仓库捡药_,
        捡药_,
        扔药_,
        沙城存药_,
        沙城取药_,
        补充物品_,

        // 地图行走;
        找到NPC_,
        走到指定地图_,
        走到指定坐标点_,
        判断是否到达指定坐标点_,

        需要脱困_,
        已经到达指定地点_,
        已经达指定点附近_,
        走到指定点附近_,
        随机到点附近_,
        等待停止移动_,
        等待到达附近_,

        交军机任务_,
        去交军机地图_,

        去打BOSS_,

        专注材料行购买_,
        守点挂机战斗_,
        守点挂机_,

        一切正常_,
    }
    public class 挂机人物_
    {
        public static string lpClassName = "LDPlayerMainFrame";
        public static TimeSpan 监控间隔 = new TimeSpan(0, 2, 0);
        public string 配置段键 { get; set; }
        public List<挂机人物_> 人物列表 { get; set; }
        public 挂机人物_()
        {
            this.模拟器已经启动 = false;
            this.组队任务菜单 = new 组队任务菜单_(new List<string>());
            this.包裹 = new 包裹_(this);
            this.BOSS表 = new Boss刷新表_(this);
            this.最近要打的Boss表 = new List<Boss提醒_>();
            this.关注的BOSS = new List<_Boss表项_>();
            this.临时过图路径 = new Stack<门点及目标_>();
            this.过图路径 = new Stack<门点及目标_>();
            this.设置窗口 = new 设置窗口_(this);
            this.宠物 = new 宠物_(this);
            this.攻击模式 = new 攻击模式_(this);
            this.任务关注怪物 = new Dictionary<string, 怪物_>();
            this.雷达 = new 雷达窗口_(this);
            this.聊天监控 = new 聊天窗口_(this);
            this.预存的任务栈 = new Stack<任务名_>();
            this.已经到达位置栈 = new Stack<bool>();
            this.当前要去的点栈 = new Stack<地图点_>();
            this.当前要去的地图栈 = new Stack<地图_>();
            this.未完成任务列表 = new List<int>();
            this.动作 = new List<Func<任务名_>>();
            this.上个任务名 = 任务名_.无_;
            this.当前任务名 = 任务名_.启动模拟器_;
            this.预存的任务 = 任务名_.无_;
            this.窗口句柄 = IntPtr.Zero;
            this.已经初始设置 = false;
            this.立即小退 = false;
            this.下线等待时间 = new TimeSpan(0, 1, 0);
            this.小退时间 = DateTime.MinValue;

            this.不领取拉镖礼盒 = false;
            this.需要补充 = true;
            this.随机门点序号 = -1;
            this.当前任务索引 = -1;
            this.随机次数 = 0;
            this.冰泉次数 = 0;
            this.红毒次数 = 0;
            this.绿毒次数 = 0;
            this.道符次数 = 0;
            this.包裹监控间隔 = 20;
            this.当前王城任务地图分类 = 地图分类_.无_;
            this.当前军机 = -1;
            this.定点挂机坐标 = new 坐标_(-1, -1);

            this.镖车监控线程 = new 镖车监控_(this);
            this.镖车监控开始时间 = DateTime.Now;
            this.异常监控线程 = new 异常监控_(this);
            this.异常监控线程.异地登录事件 += 异地登录事件处理;
            this.异常监控线程.断开连接事件 += 断开连接事件理;
            this.异常监控线程.超时事件 += 断开连接事件理;
            this.出现异常不在处理 = false;
            this.连接超时 = false;
            this.连续执行任务 = false;
            this.剩余炼狱时长 = new TimeSpan(0, 0, 0);
        }

        public bool 断开连接事件理()
        {
            this.连接超时 = true;
            return true;
        }

        public bool 异地登录事件处理()
        {
            this.出现异常不在处理 = true;
            return true;
        }

        public void 输出(string 内容)
        {
            其他_.打印(this.名称 + ":  " + 内容);
        }

        public void 调试输出(string 内容)
        {
#if _调试_
            其他_.打印(this.设置.名称 + "-调试-:  " + 内容);
#endif
        }
        public bool 自动购买炼狱时间 { get; set; }
        public bool 需要补充 { get; set; }
        public List<_Boss表项_> 关注的BOSS { get; set; }
        public int 随机门点序号 { get; set; }
        public List<int> 未完成任务列表 { get; set; }
        public int 当前任务索引 { get; set; }
        public bool 不领取拉镖礼盒 { get; set; }
        public bool 我是队长 { get; set; }

        public 消息基类_ 沟通消息 { get; set; }
        public 技能_ 技能 { get; set; }
        public IntPtr 窗口句柄 { get; set; }
        public bool 已经初始设置 { get; set; }

        public string 指定接受的军机任务 { get; set; }

        public bool 模拟器已经启动 { get;  set; }

        public Boss刷新表_ BOSS表 { get; set; }
        public List<Boss提醒_> 最近要打的Boss表 { get; set; }
        public 设置窗口_ 设置窗口 { get; private set; }
        public 宠物_ 宠物 { get; private set; }
        public 雷达窗口_ 雷达 { get; private set; }
        public 聊天窗口_ 聊天监控 { get; private set; }
        public Dictionary<string, 怪物_> 任务关注怪物 { get; private set; }
        public Dictionary<string, 怪物_> 指定关注怪物 { get; private set; }

        public 攻击模式_ 攻击模式 { get; private set; }

        public bool 要找法师宝宝 { get; set; }
        public string 姓名 { get; set; }
        public string 职业 { get; set; }
        public int 等级 { get; set; }
        public int 当前军机 { get; set; }
        public int 当前挖矿索引 { get; set; }
        public int 买药取药最大数量 { get; set; }
        public int 当前空包裹数量 { get; set; }
        public int 当前任务已完成积分 { get; set; }
        public List<Func<任务名_>> 动作 { get; set; }
        public 任务名_ 上个任务名 { get; set; }

        public bool 专注购买声望 { get; private set; }

        public 组队任务菜单_ 组队任务菜单 { get; private set; }
        public 任务名_ 当前任务名 { get; set; }
        public Stack<门点及目标_> 过图路径 { get; set; }
        public Stack<门点及目标_> 临时过图路径 { get; set; }

        public DateTime 开始挂机时间 { get; set; }
        internal 包裹_ 包裹 { get; private set; }
        public int 随机次数 { get; set; }
        public int 冰泉次数 { get; set; }
        public int 红毒次数 { get; set; }
        public int 绿毒次数 { get; set; }
        public int 道符次数 { get; set; }
        public DateTime 上次监控时间 { get; set; }
        public DateTime 上次监控包裹时间 { get; set; }
        public Stack<任务名_> 预存的任务栈 { get; set; }
        public Stack<bool> 已经到达位置栈 { get; set; }
        public Stack<地图点_> 当前要去的点栈 { get; set; }
        public Stack<地图_> 当前要去的地图栈 { get; set; }

        public 任务名_ 预存的任务 { get; set; }
        public bool 已经到达位置 { get; set; }
        public 地图点_ 当前要去的点 { get; set; }
        public 地图_ 当前要去的地图 { get; set; }
        public 坐标_ 定点挂机坐标 { get; set; }

        public int 包裹监控间隔 { get;  set; }

        public 镖车监控_ 镖车监控线程 { get; private set; }
        public DateTime 镖车监控开始时间 { get; set; }
        public 异常监控_ 异常监控线程 { get; private set; }
        public bool 出现异常不在处理 { get; private set; }
        public bool 连接超时 { get; private set; }
        public bool 跟随领队 { get; private set; }
        public bool 连续执行任务 { get; set; }
        public TimeSpan 剩余炼狱时长 { get;  set; }
        public 地图分类_ 当前王城任务地图分类 { get; set; }
        public bool 立即小退 { get; set; }


        public 坐标_ 守点坐标 { get; set; }
        public 地图_ 守点地图 { get; set; }
        public Point 守点像素 { get; set; }

        public TimeSpan 下线等待时间 { get; set; }
        public DateTime 小退时间;

        internal bool? 专打boss;
        internal List<int> 专打boss序号;
        internal bool? Boss优先;
        internal bool? 军机任务;
        internal bool 是左侧人物;

        public string 二级密码 { get; internal set; }
        public bool? 特殊挂机 { get; internal set; }
        public bool? 捡药 { get; internal set; }
        public bool? 买药 { get; internal set; }
        public bool? 扔药 { get; internal set; }
        public bool? 材料行购买 { get; internal set; }
        public int 买药库存数量 { get; internal set; }
        public int 扔药库存数量 { get; internal set; }
        public string 材料行购买物品名 { get; internal set; }
        public bool? 命令模式 { get; internal set; }
        public string 号令角色名 { get; internal set; }
        public bool? 专打怪物 { get; internal set; }
        public List<string> 专打怪物名列表 { get; internal set; }
        public bool? 主动攻击 { get; internal set; }
        public bool? 主动施毒 { get; internal set; }
        public bool? 主动捡物 { get; internal set; }
        public bool? 遇人回避 { get; internal set; }
        public bool? 高级怪物 { get; internal set; }
        public List<string> 高级怪物列表 { get; internal set; }
        public bool? 组队设置 { get; internal set; }
        public List<string> 组队成员列表 { get; internal set; }
        public bool? 王城任务 { get; internal set; }
        public bool? 王城诏令 { get; internal set; }
        public bool? 声望任务 { get; internal set; }
        public bool? 骑兵任务 { get; internal set; }
        public bool? 押镖任务 { get; internal set; }
        public bool? 挖矿任务 { get; internal set; }
        public bool? 论武任务 { get; internal set; }
        public bool? 无需设置 { get; internal set; }
        public bool? 输出日志 { get; internal set; }
        public bool? 开启录屏 { get; internal set; }


        public bool? 自动购买金币 { get; internal set; }
        public 购买设置_ 购买设置 { get; internal set; }
        public string 挂机地图名 { get; internal set; }
        public bool? 定点挂机 { get; internal set; }
        public string 名称 { get; internal set; }
        public int 启动序号 { get; internal set; }

        public void 执行(List<挂机人物_> 人物列表)
        {
            if (this.出现异常不在处理) return;

            bool 多模拟器执行 = 人物列表.Count > 1;
            if (this.人物列表 == null) this.人物列表 = 人物列表;

            if (this.当前任务名 == 任务名_.无_)
            {
                其他_.延迟(其他_.时长_1000);
                输出("无任务");
                return;
            }
            if (this.当前任务名 == 任务名_.启动模拟器_)
            {
                if (this.小退时间 != DateTime.MinValue)
                {
                    var 休息时间 = DateTime.Now - this.小退时间;
                    if (休息时间 < this.下线等待时间)
                    {
                        其他_.延迟(其他_.时长_1000);
                        return;
                    }
                    this.下线等待时间 = new TimeSpan(0, 1, 0);
                    this.小退时间 = DateTime.MinValue;
                }
                if (!this.模拟器已经启动)
                {
                    多开器操作_.按序号启动模拟器(this.启动序号);
                }
                this.模拟器已经启动 = true;

                this.窗口句柄 = 窗口_.FindWindow(lpClassName, this.名称);

                if (this.窗口句柄 == IntPtr.Zero)
                {
                    输出("模拟器没能正常启动");
                    this.当前任务名 = 任务名_.重启模拟器_;
                    return;
                }
                if (窗口_.窗口是最小化的(this.窗口句柄))
                {
                    窗口_.恢复窗口(this.窗口句柄);
                    其他_.延迟(其他_.时长_2000);
                }
                输出("置顶窗口");
                窗口_.置顶窗口(this.窗口句柄);

                其他_.延迟(其他_.时长_2000);

                输出("刷新窗口");
                窗口_.刷新窗口(this.窗口句柄);
                其他_.延迟(其他_.时长_2000);
                this.当前任务名 = 任务名_.启动游戏_;
                for (var i = 0; i < 100; i++)
                {
                    if (图像_.查找文字("关闭应用", 432, 393, 530, 431).X != -1)
                    {
                        键鼠_.左键单击(453, 482);
                        其他_.延迟(其他_.时长_2000);
                    }
                    if (UI_.找到游戏图标().X != -1 || UI_.查找游戏标签图标().X != -1)
                    {
                        输出("模拟器已经启动完成");
                        return;
                    }
                    if (i > 10)
                    {
                        // 关闭可能弹出的广告
                        键鼠_.左键单击(924, 108);
                    }
                    其他_.延迟(其他_.时长_2000);
                }
                输出("启动等待时间过长");
                this.当前任务名 = 任务名_.重启模拟器_;
                return;
            }

            准备动作();

            if (动作.Count <= 0)
            {
                return;
            }

            if (多模拟器执行)
            {
                其他_.延迟(其他_.时长_2000);
                窗口_.置顶窗口(this.窗口句柄);
                其他_.延迟(其他_.时长_2000);
            }
            for (var ii = 0; ii < 动作.Count; ii++)
            {
                var fc = 动作[ii];
                this.上个任务名 = this.当前任务名;
                try
                {
                    this.当前任务名 = fc();
                }
                catch (ThreadAbortException e)
                {
                    输出("挂机进程停止");
                    this.当前任务名 = 任务名_.无_;
                    return;
                }
                catch (Exception e)
                {
                    其他_.打印("********************************************");
                    输出(e.Message);
                    其他_.打印("********************************************");
                    switch (this.上个任务名)
                    {
                        case 任务名_.已经到达挂机地图_:
                        case 任务名_.监控挂机状态_:
                            this.预存的任务 = 任务名_.监控挂机状态_;
                            操作_.恢复默认值(this);
                            break;
                        case 任务名_.走到指定坐标点_:
                        case 任务名_.判断是否到达指定坐标点_:
                        case 任务名_.需要脱困_:
                        case 任务名_.已经到达指定地点_:
                        case 任务名_.已经达指定点附近_:
                        case 任务名_.走到指定点附近_:
                        case 任务名_.随机到点附近_:
                        case 任务名_.等待停止移动_:
                        case 任务名_.等待到达附近_:
                        case 任务名_.正式开始挂机_:
                        case 任务名_.去挂机地图_:
                        case 任务名_.补充物品_:
                        case 任务名_.走到指定地图_:
                        case 任务名_.去打BOSS_:
                        case 任务名_.找到NPC_:
                        case 任务名_.去海岛等待镖车_:
                        case 任务名_.完成拉镖任务_:
                            this.预存的任务 = 任务名_.正式开始挂机_;
                            操作_.恢复默认值(this);
                            break;
                        case 任务名_.交军机任务_:
                        case 任务名_.去交军机地图_:
                            this.预存的任务 = 任务名_.完成当前王城任务_;
                            操作_.恢复默认值(this);
                            break;
                        case 任务名_.军机令任务_:
                        case 任务名_.押镖任务_:
                        case 任务名_.去海岛打开押镖礼盒_:
                        case 任务名_.声望任务_:
                        case 任务名_.王城任务_:
                        case 任务名_.骑兵任务_:
                        case 任务名_.挖矿任务_:
                        case 任务名_.论武任务_:
                        case 任务名_.领取奖励_:
                        case 任务名_.完成声望任务_:
                        case 任务名_.完成当前王城任务_:
                        case 任务名_.完成所有王城任务_:
                        case 任务名_.去沙城买药_:
                        case 任务名_.海岛存药_:
                        case 任务名_.结束买药存药_:
                        case 任务名_.沙城仓库扔药_:
                        case 任务名_.沙城仓库捡药_:
                        case 任务名_.捡药_:
                        case 任务名_.扔药_:
                        case 任务名_.沙城存药_:
                        case 任务名_.沙城取药_:
                            this.预存的任务 = this.上个任务名;
                            操作_.恢复默认值(this);
                            break;
                    }
                    this.当前任务名 = 任务名_.重启模拟器_;
                }
            }
        }

        private void 添加动作(Func<任务名_> func)
        {
            this.动作.Add(func);
        }

        private void 清除动作()
        {
            this.动作.Clear();
        }

        public void 准备动作(bool 清除原有动作 = true)
        {
            if (this.连接超时)
            {
                this.连接超时 = false;
                其他_.延迟(其他_.时长_1000);
                this.清除动作();
                this.添加动作(() => 任务名_.重启模拟器_);
                return;
            }
            if (清除原有动作) this.清除动作();
            this.输出("当前任务: " + this.当前任务名.ToString());
            switch (this.当前任务名)
            {
                case 任务名_.去打BOSS_:
                    {
                        this.输出("准备去打BOSS");
                        其他_.延迟(其他_.时长_1000);
                        return;
                    }
                case 任务名_.需要脱困_:
                    {
                        this.添加动作(() => 操作_.需要脱困(this));
                        return;
                    }
                case 任务名_.已经到达指定地点_:
                    {
                        this.添加动作(() => 操作_.已经到达指定地点(this));
                        return;
                    }
                case 任务名_.已经达指定点附近_:
                    {
                        this.添加动作(() => 操作_.已经达指定点附近(this));
                        return;
                    }
                case 任务名_.走到指定点附近_:
                    {
                        this.添加动作(() => 操作_.走到指定点附近(this));
                        return;
                    }
                case 任务名_.等待到达附近_:
                    {
                        this.添加动作(() => 操作_.等待到达附近(this));
                        return;
                    }
                case 任务名_.等待停止移动_:
                    {
                        this.添加动作(() => 操作_.等待停止移动(this));
                        return;
                    }
                case 任务名_.随机到点附近_:
                    {
                        this.添加动作(() => 操作_.随机到点附近(this));
                        return;
                    }
                case 任务名_.走到指定坐标点_:
                    {
                        this.添加动作(() => 操作_.走到指定坐标点(this));
                        return;
                    }
                case 任务名_.走到指定地图_:
                    {
                        this.添加动作(() => 操作_.走到指定地图(this));
                        return;
                    }
                case 任务名_.找到NPC_:
                    {
                        this.添加动作(() => 操作_.找到NPC(this));
                        return;
                    }
                case 任务名_.捡药_:
                    {
                        this.添加动作(() => 操作_.捡药(this));
                        return;
                    }
                case 任务名_.扔药_:
                    {
                        this.添加动作(() => 操作_.扔药(this));
                        return;
                    }
                case 任务名_.沙城取药_:
                    {
                        this.添加动作(() => 操作_.沙城取药(this));
                        return;
                    }
                case 任务名_.沙城存药_:
                    {
                        this.添加动作(() => 操作_.沙城存药(this));
                        return;
                    }
                case 任务名_.沙城仓库扔药_:
                case 任务名_.沙城仓库捡药_:
                    {
                        this.添加动作(() => 操作_.去沙城仓库扔或捡药(this));
                        return;
                    }
                case 任务名_.结束买药存药_:
                    {
                        this.添加动作(() => 操作_.结束买药存药(this));
                        return;
                    }
                case 任务名_.海岛存药_:
                    {
                        this.添加动作(() => 操作_.海岛存药(this));
                        return;
                    }
                case 任务名_.去沙城买药_:
                    {
                        this.添加动作(() => 操作_.去沙城买药(this));
                        return;
                    }
                case 任务名_.完成所有王城任务_:
                    {
                        this.添加动作(() => 操作_.完成所有王城任务(this));
                        return;
                    }
                case 任务名_.去海岛打开押镖礼盒_:
                    {
                        this.添加动作(() => 操作_.去海岛打开押镖礼盒(this));
                        return;
                    }
                case 任务名_.去海岛等待镖车_:
                    {
                        this.添加动作(() => 操作_.去海岛等待镖车(this));
                        return;
                    }
                case 任务名_.完成拉镖任务_:
                    {
                        this.添加动作(() => 操作_.完成拉镖任务(this));
                        return;
                    }
                case 任务名_.押镖任务_:
                    {
                        this.添加动作(() => 操作_.押镖任务(this));
                        return;
                    }
                case 任务名_.挖矿任务_:
                    {
                        this.添加动作(() => 操作_.挖矿任务(this));
                        return;
                    }
                case 任务名_.骑兵任务_:
                    {
                        this.添加动作(() => 操作_.骑兵任务(this));
                        return;
                    }
                case 任务名_.完成当前王城任务_:
                    {
                        this.添加动作(() => 操作_.完成当前王城任务(this));
                        return;
                    }
                case 任务名_.王城任务_:
                    {
                        this.添加动作(() => 操作_.王城任务(this));
                        return;
                    }
                case 任务名_.论武任务_:
                    {
                        this.添加动作(() => 操作_.论武任务(this));
                        return;
                    }
                case 任务名_.完成声望任务_:
                    {
                        this.添加动作(() => 操作_.完成声望任务(this));
                        return;
                    }
                case 任务名_.声望任务_:
                    {
                        this.添加动作(() => 操作_.声望任务(this));
                        return;
                    }
                case 任务名_.交军机任务_:
                    {
                        this.添加动作(() => 操作_.交军机任务(this));
                        return;
                    }
                case 任务名_.去交军机地图_:
                    {
                        this.添加动作(() => 操作_.去交军机地图(this));
                        return;
                    }
                case 任务名_.军机令任务_:
                    {
                        this.添加动作(() => 操作_.军机令任务(this));
                        return;
                    }
                case 任务名_.监控挂机状态_:
                    {
                        this.添加动作(() => 操作_.监控挂机状态(this));
                        return;
                    }
                case 任务名_.已经到达挂机地图_:
                    {
                        this.添加动作(() => 操作_.开始战斗(this));
                        return;
                    }
                case 任务名_.去挂机地图_:
                    {
                        this.添加动作(() => 操作_.去挂机地图(this));
                        return;
                    }
                case 任务名_.守点挂机战斗_:
                    {
                        this.添加动作(() => 操作_.守点挂机战斗(this));
                        return;
                    }
                case 任务名_.守点挂机_:
                    {
                        this.添加动作(() => 操作_.守点挂机(this));
                        return;
                    }
                case 任务名_.正式开始挂机_:
                    {
                        this.添加动作(() => 操作_.正式开始挂机(this));
                        return;
                    }
                case 任务名_.补充物品_:
                    {
                        this.添加动作(() => 操作_.补充物品(this));
                        return;
                    }
                case 任务名_.初始设置_:
                    {
                        this.添加动作(() => 操作_.设置初始值(this));
                        return;
                    }
                case 任务名_.小退后登陆_:
                    {
                        this.添加动作(() => 操作_.小退后登陆(this));
                        return;
                    }
                case 任务名_.判断游戏状态_:
                    {
                        this.添加动作(() => 操作_.判断游戏状态(this));
                        return;
                    }
                case 任务名_.登陆游戏_:
                    {
                        this.添加动作(() => 操作_.登陆游戏(this));
                        return;
                    }
                case 任务名_.启动游戏_:
                    {
                        this.添加动作(() => 操作_.启动游戏(this));
                        return;
                    }
                case 任务名_.重启模拟器_:
                    {
                        this.添加动作(() => 操作_.重启模拟器(this));
                        return;
                    }
                case 任务名_.专注材料行购买_:
                    {
                        this.添加动作(() => 操作_.专注材料行购买(this));
                        return;
                    }
                default:
                    return;
            }
        }
    }

    class 路径队列_
    {
        public 路径队列_()
        {
            this.队列 = new Queue<快捷传送_>();
            this.是终结的 = false;
        }
        public Queue<快捷传送_> 队列 { get; set; }
        public bool 是终结的 { get; set; }
    }

    class 操作_
    {
        public static void 更新任务列表记录(挂机人物_ 人物)
        {
            var 列表 = 人物.未完成任务列表;
            var 索引 = 人物.当前任务索引;
            列表.RemoveAt(索引);
            设置任务记录(人物, "未完成列表", string.Join(",", 列表.Select(n => n.ToString()).ToArray()));
            设置任务记录(人物, "列表记录时间");
        }
        public static void 设置任务记录(挂机人物_ 人物, string 节名, string 值 = "")
        {
            var 段名 = 人物.配置段键 + "_任务";
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var 当前段 = (AppSettingsSection)config.GetSection(段名);
            if (当前段 == null)
            {
                当前段 = new AppSettingsSection();
                config.Sections.Add(段名, 当前段);
            }
            人物.输出("保存: " + 节名);
            当前段.Settings.Remove(节名);
            if (值 == "") 值 = DateTime.Now.ToString("yyyy-MM-dd");
            当前段.Settings.Add(节名, 值);
            config.Save(ConfigurationSaveMode.Modified);
        }

        public static string 读取任务记录(挂机人物_ 人物, string 节名)
        {
            var 段名 = 人物.配置段键 + "_任务";
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var 当前段 = (AppSettingsSection)config.GetSection(段名);
            if (当前段 != null)
            {
                if (当前段.Settings[节名] != null) return 当前段.Settings[节名].Value;
            }
            return "";
        }

        public static 任务名_ 随机做任务(挂机人物_ 人物)
        {
            var 当前 = DateTime.Now;
            if (当前.TimeOfDay > new TimeSpan(23, 50, 0))
            {
                人物.输出("时间太晚了, 任务无法完成.");
                return 任务名_.正式开始挂机_;
            }

            string[] 任务名数组 = new string[] {
                 "论武任务",
                 "王城任务",
                 "声望任务",
                 "骑兵任务",
                 "挖矿任务",
                 "押镖任务",
            };

            任务名_[] 返回任务数组 = new 任务名_[] {
                任务名_.论武任务_,
                任务名_.王城任务_,
                任务名_.声望任务_,
                任务名_.骑兵任务_,
                任务名_.挖矿任务_,
                任务名_.押镖任务_,
            };

            Rectangle[] 确认范围列表 = new Rectangle[]
            {
                Rectangle.Empty,
                Rectangle.FromLTRB(740, 300, 780, 320),
                Rectangle.FromLTRB(740, 347, 780, 367),
                Rectangle.FromLTRB(740, 390, 780, 410),
                Rectangle.FromLTRB(740, 435, 780, 455),
                Rectangle.FromLTRB(740, 482, 780, 502),
            };

            int[] 任务最高积分数据 = new int[] { 0, 27, 9, 5, 10, 10 };
            var 未完成记录文本数据 = "0,1,2,3,4,5";
            var 读取列表记录时间 = 读取任务记录(人物, "列表记录时间");
            var 当前时间 = 当前.ToString("yyyy-MM-dd");
            if (当前时间 == 读取列表记录时间)
            {
                未完成记录文本数据 = 读取任务记录(人物, "未完成列表");
            }
            else
            {
                设置任务记录(人物, "列表记录时间");
                设置任务记录(人物, "未完成列表", 未完成记录文本数据);
            }
            人物.输出("当前未完成的: " + 未完成记录文本数据);

            var 未完成数据列表 = 未完成记录文本数据.Split(',').Select(s => int.Parse(s)).ToList();

            var 列表索引 = 其他_.随机数(未完成数据列表.Count);
            int 索引 = 未完成数据列表[列表索引];
            // 分配一个任务
            人物.未完成任务列表 = 未完成数据列表;
            人物.当前任务索引 = 列表索引;

            if (!这个任务是否需要做(索引))
            {
                return 任务名_.正式开始挂机_;
            }

            return 分配任务(索引);

            任务名_ 分配任务(int 当前任务索引)
            {
                var 任务记录 = 读取任务记录(人物, 任务名数组[当前任务索引]);
                var 现在时间 = DateTime.Now.ToString("yyyy-MM-dd");
                人物.输出("现在时间: " + 现在时间);
                人物.输出(任务名数组[当前任务索引] + ": " + 任务记录);

                if (任务记录 != 现在时间)
                {
                    if (当前任务索引 == 0)
                    {
                        return 任务名_.论武任务_;
                    }
                    UI_.打开今日挑战();
                    人物.当前任务已完成积分 = 任务积分是否满足(确认范围列表[当前任务索引]);
                    if (人物.当前任务已完成积分 < 任务最高积分数据[当前任务索引])
                    {
                        if (当前任务索引 == 1)
                        {
                            UI_.关闭今日挑战();
                        }
                        return 返回任务数组[当前任务索引];
                    }
                    else
                    {
                        人物.输出("已完成 " + 任务名数组[当前任务索引]);
                        更新任务列表记录(人物);
                        设置任务记录(人物, 任务名数组[当前任务索引]);
                    }
                    UI_.关闭今日挑战();
                }
                return 任务名_.正式开始挂机_;
            }

            bool 这个任务是否需要做(int 当前任务索引)
            {
                switch (当前任务索引)
                {
                    case 0:
                        return 人物.论武任务.HasValue && 人物.论武任务.Value;
                    case 1:
                        return 人物.王城诏令.HasValue && 人物.王城诏令.Value;
                    case 2:
                        return 人物.声望任务.HasValue && 人物.声望任务.Value;
                    case 3:
                        return 人物.骑兵任务.HasValue && 人物.骑兵任务.Value;
                    case 4:
                        return 人物.挖矿任务.HasValue && 人物.挖矿任务.Value;
                    case 5:
                        return 人物.押镖任务.HasValue && 人物.押镖任务.Value;
                }
                return false;
            }

        }

        public static bool 监控聊天频道(挂机人物_ 人物, 聊天分类及内容_[] 内容)
        {
            foreach (var s in 内容)
            {
                if (s.分类 == 聊天分类_.私聊消息_)
                {
                    人物.输出("私聊: " + s.内容);
                    MainWindow.执行线程.暂停();
                    var 详细内容 = 人物.聊天监控.详细探测最近的聊天内容(人物.聊天监控.切换到私聊频道);
                    人物.输出("消息: " + 详细内容);
                    MainWindow.执行线程.启动();
                }
                else if (s.分类 == 聊天分类_.附近消息_)
                {
                    人物.输出("发现附近聊天");
                    MainWindow.执行线程.暂停();
                    var 详细内容 = 人物.聊天监控.详细探测最近的聊天内容(人物.聊天监控.切换到普通频道);
                    人物.输出("最近聊天: " + 详细内容);
                    MainWindow.执行线程.启动();
                }
                其他_.延迟(其他_.时长_200);
            }
            return true;
        }

        public static 任务名_ 守点挂机战斗(挂机人物_ 人物)
        {
            var 守点坐标 = 人物.守点坐标;
            人物.输出("守点坐标: " + 守点坐标.ToString());
            for (var n = 0; n < 20; n++)
            {
                UI_.点击捡物();
                其他_.延迟(其他_.时长_400);
            }
            var 当前坐标 = UI_.连续识别坐标();
        重来_:
            if (!UI_.坐标点距离较近(守点坐标, 当前坐标, 1))
            {
                if (!UI_.坐标点距离较近(守点坐标, 当前坐标, 15))
                {
                    人物.输出("离开点位较远");
                    UI_.移动到地图内准确位置(人物.守点像素);

                    var 在移动 = UI_.判断角色是否在移动();
                    while (在移动)
                    {
                        其他_.延迟(其他_.时长_1000);
                        在移动 = UI_.判断角色是否在移动();
                    }

                    当前坐标 = UI_.连续识别坐标();
                }

                for (var n = 0; !UI_.坐标点距离较近(守点坐标, 当前坐标, 1); n++)
                {
                    人物.输出("调整位置");
                    UI_.移动(UI_.根据位置判断方向(当前坐标, 守点坐标, out int 时长, UI_.切换到走路()), 时长);
                    当前坐标 = UI_.连续识别坐标();
                    if (n > 10) goto 重来_;
                }
            }
            var 现在 = DateTime.Now;
            var 间隔 = 现在 - 人物.上次监控包裹时间;
            if (间隔 > new TimeSpan(0, 人物.包裹监控间隔, 0))
            {
                人物.输出("检测1次包裹");
                人物.上次监控包裹时间 = DateTime.Now;
                人物.包裹.整理包裹(true, true);
            }
            人物.输出("到达位置: " + 当前坐标.ToString());
            其他_.延迟(其他_.时长_1000);
            return 任务名_.守点挂机战斗_;
        }

        public static 任务名_ 守点挂机(挂机人物_ 人物)
        {
            人物.守点坐标 = 人物.定点挂机坐标.X != -1 ? 人物.定点挂机坐标  : UI_.连续识别坐标();
            人物.守点像素 = 人物.定点挂机坐标.X == -1?  UI_.角色在小地图中位置(true) : new Point(-1, -1);
            if (人物.守点像素.X == -1)
            {
                var 地图 = UI_.获取当前地图();
                var p = 地图.获取对应点(人物.守点坐标);
                人物.输出("估算像素坐标: X: " + p.X.ToString() + " Y: " + p.Y.ToString());
                人物.守点像素 = p;
            }
            人物.输出("探测的位置: X: " + 人物.守点像素.X.ToString() + " Y: " + 人物.守点像素.Y.ToString());
            return 任务名_.守点挂机战斗_;
        }

        public static 任务名_ 正式开始挂机(挂机人物_ 人物)
        {
            人物.连续执行任务 = false;
            人物.输出("正式开始挂机");
            if (人物.特殊挂机.HasValue && 人物.特殊挂机.Value)
            {
                if (人物.买药.HasValue && 人物.买药.Value  || 人物.捡药.HasValue && 人物.捡药.Value || 人物.扔药.HasValue && 人物.扔药.Value)
                {
                    人物.组队任务菜单.关闭组队任务菜单();
                    人物.包裹.整理包裹(true, true);
                    人物.买药取药最大数量 = 人物.包裹.获取物品数量(_物品_.空包裹_) + 人物.包裹.获取物品数量(_物品_.治疗药水_) - 5;

                    if (人物.买药.HasValue && 人物.买药.Value)
                    {
                        return 任务名_.海岛存药_;
                    }
                    else if (人物.扔药.HasValue && 人物.扔药.Value)
                    {
                        if (人物.无需设置.HasValue && 人物.无需设置.Value)
                        {
                            return 任务名_.沙城仓库扔药_;
                        }
                        人物.设置窗口.关闭极品拾取及自动捡物();
                        return 任务名_.沙城仓库扔药_;
                    }
                    else
                    {
                        if (人物.无需设置.HasValue && 人物.无需设置.Value)
                        {
                            return 任务名_.沙城仓库捡药_;
                        }
                        人物.设置窗口.设置物品为拾取("治疗药水", 物品设置_.极品_);
                        return 任务名_.沙城仓库捡药_;
                    }
                }
                else if (人物.命令模式.HasValue && 人物.命令模式.Value)
                {
                    人物.输出("未实现命令模式");
                    return 任务名_.无_;
                }
                else if (人物.专打怪物.HasValue && 人物.专打怪物.Value)
                {
                    人物.输出("未实现专打怪物");
                    return 任务名_.无_;
                }
                人物.输出("未实现专打boss");
                return 任务名_.无_;
            }
      
            else
            {
                if (人物.需要补充)
                {
#if _发行_
                    人物.预存的任务 = 任务名_.正式开始挂机_;
                    var 返回任务 = 操作_.补充物品(人物);
                    return 返回任务;
#endif
                }

                if (人物.关注的BOSS.Count != 0)
                {
                    人物.BOSS表.识别Boss刷新表();
                }
                if (人物.军机任务.HasValue && 人物.军机任务.Value || 人物.王城任务.HasValue && 人物.王城任务.Value)
                {
                    人物.组队任务菜单.激活任务菜单();
                }
                if (人物.军机任务.HasValue && 人物.军机任务.Value)
                {
                    var 军机任务 = 读取任务记录(人物, "军机任务");
                    人物.输出("军机记录: " + 军机任务);
                    var 当前时间是第几周 = CultureInfo.CurrentCulture.Calendar.
                        GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                    if (军机任务 != 当前时间是第几周.ToString())
                    {
                        var 已经接受了军机 = UI_.已经接了军机任务(out var 当前军机);
                        人物.当前军机 = 当前军机;
                        人物.输出(获取军机地图名(人物));
                        if (!已经接受了军机) return 任务名_.军机令任务_;
                        人物.输出("当前军机为: " + 人物.当前军机);
                        var 当前地图 = UI_.获取当前地图();
                        if (UI_.判断地图名(获取军机地图名(人物), 2))
                        {
                            return 任务名_.交军机任务_;
                        }
                    }
                }

                if (人物.王城任务.HasValue && 人物.王城任务.Value)
                {
                    var 未完成记录文本数据 = 读取任务记录(人物, "未完成列表");
                    var 当前时间 = DateTime.Now.ToString("yyyy-MM-dd");
                    if (未完成记录文本数据 != 当前时间)
                    {
                        return 随机做任务(人物);
                    }
                    else
                    {
                        var 领取 = 读取任务记录(人物, "领取奖励");
                        if (领取 != 当前时间) return 任务名_.完成所有王城任务_;
                    }
                }

                人物.组队任务菜单.队长创建组队(人物);
                人物.组队任务菜单.关闭组队任务菜单();

                if (UI_.获取当前地图() != 地图集_.获取地图(人物.挂机地图名))
                {
                    人物.需要补充 = true;
                    return 任务名_.去挂机地图_;
                }
                人物.需要补充 = true;
                return 开始战斗(人物);
            }
        }

        public static bool 处理来人事件(挂机人物_ 人物, int 人数)
        {
            人物.输出("***********周围有 " + 人数 + " 个人***********");
            return false;
        }

        public static 任务名_ 监控挂机状态(挂机人物_ 人物)
        {
            人物.连续执行任务 = false;
            var 现在 = DateTime.Now;
            人物.上次监控时间 = 现在;
            if (人物.雷达.来人监控线程.是否在运行 == false)
            {
                人物.雷达.处理来人事件 = 操作_.处理来人事件;
                人物.雷达.来人监控线程.启动();
            }

            var 还有物品 = 战斗_.发现物品或怪物() == 发现物品或怪物_.发现物品_;
            var i = 0;
            while (还有物品)
            {
                i++;
                人物.输出("发现极品, 捡取 " + i + " 次");
                UI_.点击捡物();
                UI_.关闭内挂();
                还有物品 = 其他_.循环判断(() => 战斗_.发现物品或怪物() != 发现物品或怪物_.发现物品_, 1, 500);
                if (!还有物品)
                {
                    UI_.开启内挂();
                    break;
                }
                if (DateTime.Now - 现在 > new TimeSpan(0, 1, 30))
                {
                    UI_.开启内挂();
                    break;
                }
            }

            if (UI_.你已阵亡())
            {
                人物.输出("意外死亡, 重启挂机");
                人物.雷达.来人监控线程.暂停();
                其他_.延迟(其他_.时长_10000);
                return 任务名_.重启模拟器_;
            }

            if (战斗_.有攻击目标() && 战斗_.识别攻击目标血量是否为满血())
            {
                其他_.延迟(其他_.时长_5000);
                if (战斗_.识别攻击目标血量是否为满血())
                {
                    其他_.延迟(其他_.时长_5000);
                    if (战斗_.识别攻击目标血量是否为满血())
                    {
                        // 确定是在攻击 死怪
                        人物.输出("发生了持续攻击死怪");
                        UI_.使用回城();
                        人物.雷达.来人监控线程.暂停();
                        return 任务名_.正式开始挂机_;
                    }
                }
            }

            if (人物.王城任务.HasValue && 人物.王城任务.Value && 人物.开始挂机时间.Date != 人物.上次监控时间.Date)
            {
                人物.输出("任务重置了, 开始去做任务");
                人物.雷达.来人监控线程.暂停();
                return 任务名_.正式开始挂机_;
            }

            // 监控脱离地图
            var 当前地图 = UI_.获取当前地图();

            if (当前地图 == 地图_.跃马大平原)
            {
                人物.输出("脱离了挂机地图");
                其他_.延迟(其他_.时长_10000);
                当前地图 = UI_.获取当前地图();
                if (当前地图 != 地图集_.获取地图(人物.挂机地图名))
                {
                    人物.输出("等待10秒后没有回图, 重新跑图");

                    现在 = DateTime.Now;
                    if (现在 - 人物.开始挂机时间 < new TimeSpan(0, 0, 人物.包裹监控间隔))
                    {
                        人物.需要补充 = false;
                    }
                    else
                    {
                        人物.需要补充 = true;
                    }
                    人物.雷达.来人监控线程.暂停();
                    return 任务名_.正式开始挂机_;
                }
                人物.输出("等待10秒后回图了, 继续挂机");
                return 任务名_.监控挂机状态_;
            }
            else if (当前地图 != 地图集_.获取地图(人物.挂机地图名))
            {
                if ((当前地图.属性 & 地图属性_.不可内挂_) == 0) UI_.开启内挂();
                return 任务名_.去挂机地图_;
            }

            var 间隔 = 现在 - 人物.上次监控包裹时间;
            if (间隔 > new TimeSpan(0, 人物.包裹监控间隔, 0))
            {
                if ((当前地图.属性 & 地图属性_.高级地图_) != 0)
                {
                    // 只有道士有效
                    人物.技能.使用隐身();
                }
                人物.输出("检测1次包裹");
                人物.上次监控包裹时间 = DateTime.Now;
                人物.包裹.整理包裹();
                var 空包裹 = 人物.包裹.获取物品数量(_物品_.空包裹_);
                if (空包裹 < 10)
                {
                    var 太阳水数量 = 人物.包裹.获取物品数量(_物品_.太阳神水_);
                    if (太阳水数量 > 15)
                    {
                        人物.输出("空位太少了, 使用强效太阳神水");
                        人物.包裹.使用包内物品(_物品_.太阳神水_, 15, true);
                        人物.设置窗口.设置物品为拾取("强效太阳神水", 物品设置_.不拾取_);
                        return 任务名_.监控挂机状态_;
                    }
                    // 应该是治疗满了 回城存药
                    人物.包裹.关闭包裹();
                    人物.输出("包裹太满了, 回城存药");
                    人物.需要补充 = true;
                    人物.雷达.来人监控线程.暂停();
                    return 任务名_.正式开始挂机_;
                }
                else if (空包裹 < 30)
                {
                    人物.包裹.关闭包裹();
                    人物.设置窗口.设置物品为拾取("强效太阳神水", 物品设置_.不拾取_);
                }
                else if (空包裹 > 60)
                {
                    人物.包裹.关闭包裹();
                    人物.设置窗口.设置物品为拾取("强效太阳神水", 物品设置_.普通_);
                }
                else
                {
                    人物.包裹.关闭包裹();
                }
            }

            if (当前地图.头目极品组.Count > 0)
            {
                if (战斗_.监控当前地图专注怪物列表(当前地图, out var 极品))
                {
                    // 在怪物列表里 选中怪物
                    键鼠_.左键单击(极品.点位);
                    其他_.延迟(其他_.时长_400);
                    键鼠_.左键单击(极品.点位);
                    人物.输出("攻击极品怪物: " + 极品.怪物.名称);
                }
                else
                {
                    var p = UI_.连续识别坐标();
                    var 近距离头目 = 当前地图.头目极品组.Find(g => UI_.坐标点距离较近(g.位置, p, 20));
                    if (近距离头目 != null)
                    {
                        人物.输出("去头目: " + 近距离头目.名称 + "看看");
                        人物.预存的任务 = 任务名_.已经到达挂机地图_;
                    }
                }
            }
            人物.输出("挂机状态正常");
            if (人物.关注的BOSS.Count > 0)
            {
                var 可以去打的boss = new List<Boss提醒_>();
                foreach (var boss in 人物.关注的BOSS)
                {
                    var b = Boss刷新表_.表[(int)boss];
                    var 已经过了 = DateTime.Now - b.记录时间;
                    if (b.时间 < 已经过了)
                    {
                        人物.输出(" 已经刷新了,跳过: " + boss);
                        continue;
                    }
                    var 距离刷新时间 = b.时间 - 已经过了;
                    b.时间 = 距离刷新时间;
                    if (距离刷新时间 < new TimeSpan(0, 15, 0) && 距离刷新时间 > new TimeSpan(0, 5, 0))
                    {
                        人物.输出("准备去打BOSS: " + boss);
                        可以去打的boss.Add(b);
                    }
                }
                if (可以去打的boss.Count > 0)
                {
                    foreach (var b in 可以去打的boss)
                    {
                        人物.BOSS表.查看BOSS刷新时间(b.表项);
                    }
                    人物.最近要打的Boss表 = 可以去打的boss;
                    人物.雷达.来人监控线程.退出();
                    return 任务名_.去打BOSS_;
                }
            }

            if (人物.定点挂机坐标.X != -1)
            {
                var p = UI_.连续识别坐标();
                if (!UI_.坐标点距离较近(p, 人物.定点挂机坐标, 15) && !战斗_.快速监控怪物列表())
                {
                    UI_.根据地图比例移动到大概位置(人物, 当前地图, 人物.定点挂机坐标);
                等待_:
                    if (!战斗_.快速监控怪物列表())
                    {
                        其他_.延迟(其他_.时长_1000);
                        goto 等待_;
                    }
                    UI_.开启内挂();
                    if ((当前地图.属性 & 地图属性_.高级地图_) != 0)
                    {
                        // 只有道士有效
                        其他_.延迟(其他_.时长_600);
                        人物.技能.使用隐身();
                    }
                }
            }
            return 任务名_.监控挂机状态_;
        }

        private static void 捡取物品(挂机人物_ 人物)
        {
            坐标_ p1, p2;
            var i = 0;
            do
            {
                i++;
                p1 = UI_.识别坐标();
                UI_.点击捡物();
                人物.输出("尝试拾取 " + i + " 次物品");
                其他_.延迟(其他_.时长_1000);
                p2 = UI_.识别坐标();
            }
            while (p1 != p2);
        }

        private static int 任务积分是否满足(Rectangle ret)
        {
            try
            {
                var 积分 = 图像_.识别文字(ret);
                return Convert.ToInt32(积分.Trim(), 10);
            }
            catch (Exception)
            {
                return 100;
            }
        }

        public static 任务名_ 需要脱困(挂机人物_ 人物)
        {
            人物.输出("人物被困");
            var 地图名 = UI_.识别地图名();
            if (!地图集_.有地图(地图名))
            {
                UI_.使用回城();
                其他_.延迟(其他_.时长_5000);
                return 任务名_.走到指定地图_;
            }
            var 地图 = 地图集_.获取地图(地图名);
            if ((地图.属性 & 地图属性_.不可随机_) != 0)
            {
                UI_.使用回城();
                其他_.延迟(其他_.时长_5000);
                return 任务名_.走到指定地图_;
            }
            UI_.使用随机(人物);
            return 任务名_.走到指定坐标点_;
        }

        public static 任务名_ 已经到达指定地点(挂机人物_ 人物)
        {
            人物.已经到达位置 = true;
            人物.连续执行任务 = false;

            var 位置 = 人物.当前要去的点.位置.坐标;
            if (人物.当前要去的点.支持多点.Count > 1 && 人物.随机门点序号 != -1)
            {
                位置 = 人物.当前要去的点.支持多点[人物.随机门点序号].坐标;
            }
            if (位置.X != -1)
            {
                人物.输出("已经到达指定地点: " + 位置.ToString());
                人物.输出("预存的任务: " + 人物.预存的任务.ToString());
            }
            人物.上个任务名 = 人物.当前任务名;
            人物.当前任务名 = 人物.预存的任务;
            人物.准备动作(false);
            return 人物.预存的任务;
        }

        public static 任务名_ 已经达指定点附近(挂机人物_ 人物)
        {
            var ii = 0;
            var 目标位置 = 人物.当前要去的点.位置.坐标;
            if (人物.当前要去的点.支持多点.Count > 1 && 人物.随机门点序号 != -1)
            {
                目标位置 = 人物.当前要去的点.支持多点[人物.随机门点序号].坐标;
            }

            if (人物.当前要去的点.到达附近就可以) return 任务名_.已经到达指定地点_;

            var p = UI_.连续识别坐标(10);

            if (UI_.坐标点距离较近(p, 目标位置, 2)) return 任务名_.已经到达指定地点_;

            while (true)
            {
                ii++;
                if (ii > 20) throw new Exception("未到达指定地点");

                p = UI_.连续识别坐标(10);

                UI_.移动(UI_.根据位置判断方向(p, 目标位置, out int t, UI_.是跑步()), t);

                坐标_ p3 = UI_.连续识别坐标(10);
                if (p.X == p3.X && p.Y == p3.Y) return 任务名_.需要脱困_;

                if (UI_.坐标点距离较近(p3, 目标位置, 1)) return 任务名_.已经到达指定地点_;
            }
        }

        public static 任务名_ 走到指定点附近(挂机人物_ 人物)
        {
            var 像素点 = 人物.当前要去的点.位置.像素点;
            var 到达 = UI_.移动到地图内准确位置(像素点);
            if (!到达) return 任务名_.需要脱困_;
            if (人物.当前要去的点.到达附近就可以)
            {
                return 任务名_.等待到达附近_;
            }
            return 任务名_.等待停止移动_;
        }

        public static 任务名_ 等待到达附近(挂机人物_ 人物)
        {
            var 位置 = 人物.当前要去的点.位置.坐标;
            GraphicsPath 多边形 = new GraphicsPath();
            var 范围 = Rectangle.FromLTRB(位置.X - 8, 位置.Y - 8, 位置.X + 8, 位置.Y + 8);
            多边形.AddRectangle(范围);
            多边形.CloseFigure();
            var p = UI_.连续识别坐标();
            var 到达 = 多边形.IsVisible((Point)p);
            if (!到达)
            {
                if (!UI_.坐标点距离较近(p, 位置, 20))
                {
                    人物.连续执行任务 = false;
                }
                if (UI_.判断角色是否在移动())
                {
                    return 任务名_.等待到达附近_;
                }
                return 任务名_.走到指定点附近_;
            }
            键鼠_.左键单击(640, 400);
            其他_.延迟(其他_.时长_600);
            return 任务名_.已经到达指定地点_;
        }

        public static 任务名_ 等待停止移动(挂机人物_ 人物)
        {
            var 在移动 = UI_.判断角色是否在移动();
            if (在移动)
            {
                var 目标位置 = 人物.当前要去的点.位置.坐标;
                if (人物.当前要去的点.支持多点.Count > 1 && 人物.随机门点序号 != -1)
                {
                    目标位置 = 人物.当前要去的点.支持多点[人物.随机门点序号].坐标;
                }

                var 现在位置 = UI_.连续识别坐标();
                if (!UI_.坐标点距离较近(现在位置, 目标位置, 40))
                {
                    人物.连续执行任务 = false;
                }
                人物.输出("角色还在移动, 继续等待");
                其他_.延迟(其他_.时长_1000 / 2);
                return 任务名_.等待停止移动_;
            }
            var 目标 = 人物.当前要去的点.位置.坐标;
            if (人物.当前要去的点.支持多点.Count > 1 && 人物.随机门点序号 != -1)
            {
                目标 = 人物.当前要去的点.支持多点[人物.随机门点序号].坐标;
            }
            var 现在 = UI_.连续识别坐标();
            if (UI_.坐标点距离较近(目标, 现在, 2)) return 任务名_.已经到达指定地点_;
            人物.输出("角色已经到达, 等待完成");
            return 任务名_.已经达指定点附近_;
        }

        public static 任务名_ 随机到点附近(挂机人物_ 人物)
        {
            var 点位组 = 人物.当前要去的点.支持多点.Select(a => a.像素点).ToArray();
            人物.随机门点序号 = UI_.随机到合格点(人物.当前要去的点.所在地图, 人物, 点位组, 人物.当前要去的点.所在地图.获取随机接受范围值());
            return 任务名_.等待停止移动_;
        }

        public static 任务名_ 走到指定坐标点(挂机人物_ 人物)
        {
            if (人物.当前要去的点 == null) throw new Exception("没有目标NPC");

            人物.输出(人物.当前要去的点.名称);

            var 地图 = UI_.获取当前地图();
            if (人物.当前要去的点.所在地图 != 地图) throw new Exception("目标位置不在当前地图");

            if (人物.当前要去的点.实现快速接近)
            {
                return 人物.当前要去的点.快速接近(人物);
            }
            if (人物.当前要去的点.位置.坐标.X == -1)
            {
                throw new Exception("点是虚拟的");
            }

            var 坐标 = UI_.连续识别坐标();
            if (UI_.坐标点距离较近(坐标, 人物.当前要去的点.位置.坐标, 2))
            {
                return 任务名_.已经到达指定地点_;
            }
            if (UI_.坐标点距离较近(坐标, 人物.当前要去的点.位置.坐标, 5))
            {
                return 任务名_.已经达指定点附近_;
            }
            if (UI_.坐标点距离较近(坐标, 人物.当前要去的点.位置.坐标, 地图.获取随机接受范围值()))
            {
                return 任务名_.走到指定点附近_;
            }
            return 任务名_.随机到点附近_;
        }

        public static 任务名_ 捡药(挂机人物_ 人物)
        {
            if (人物.立即小退)
            {
                人物.立即小退 = false;
                return 任务名_.重启模拟器_;
            }
            挂机人物_ 扔药的 = null;
            挂机人物_ 捡药的 = null;
            if (人物.人物列表 != null && 人物.人物列表.Count > 1)
            {
                扔药的 = 人物.人物列表.Find(ii => ii.扔药.HasValue && ii.扔药.Value);
                捡药的 = 人物.人物列表.Find(i => i.捡药.HasValue && i.捡药.Value);
            }
            if (扔药的 == null || 捡药的 == null)
            {
                if (捡药的 == null)
                {
                    var 目标 = new 坐标_(7, 11);
                    var p = UI_.连续识别坐标();
                    if (!UI_.坐标点距离较近(p, 目标, 2))
                    {
                        UI_.移动(UI_.根据位置判断方向(p, 目标, out var t, !UI_.切换到走路()), t);
                    }
                    return 人物.预存的任务;
                }
                其他_.延迟(其他_.时长_1000);
                return 任务名_.捡药_;
            }

            if (捡药的.沟通消息 == null) 捡药的.沟通消息 = new 通知消息_();
            var 捡药消息 = (通知消息_)捡药的.沟通消息;
            if (扔药的.沟通消息 == null) 扔药的.沟通消息 = new 通知消息_();
            var 扔药消息 = (通知消息_)扔药的.沟通消息;

            if (人物 == 捡药的)
            {
                if (扔药的.预存的任务 == 任务名_.沙城取药_)
                {
                    捡药消息.已经准备好 = false;
                    捡取物品(人物);
                    return 任务名_.沙城存药_;
                }
                return 任务名_.捡药_;
            }
            if (人物 == 扔药的)
            {
                if (人物.预存的任务 == 任务名_.扔药_)
                {
                    if (!捡药消息.已经准备好) return 任务名_.捡药_;
                    var 目标 = new 坐标_(7, 11);
                    var p = UI_.连续识别坐标();
                    if (!UI_.坐标点距离较近(p, 目标, 1))
                    {
                        UI_.移动(UI_.根据位置判断方向(p, 目标, out var t, !UI_.切换到走路()), t);
                    }
                }
            }
            return 人物.预存的任务;
        }

        public static bool 扔药时监控来人(挂机人物_ 人物, int 人数)
        {
            if (人数 >= 2)
            {
                var 扔药的 = 人物.人物列表.Find(i => i.扔药.HasValue && i.扔药.Value);
                if (扔药的 != null)
                {
                    扔药的.立即小退 = true;
                    扔药的.下线等待时间 = new TimeSpan(0, 5, 0);
                }
                var 捡药的 = 人物.人物列表.Find(i => i.捡药.HasValue && i.捡药.Value);
                if (捡药的 != null)
                {
                    捡药的.立即小退 = true;
                    捡药的.下线等待时间 = new TimeSpan(0, 6, 0);
                }
                人物.输出("房间来人了");
            }
            return true;
        }

        public static 任务名_ 扔药(挂机人物_ 人物)
        {
            if (人物.雷达.来人监控线程.是否在运行 == false)
            {
                人物.雷达.处理来人事件 = 扔药时监控来人;
                人物.雷达.来人监控线程.启动();
            }
            var 包裹 = 人物.包裹;
            包裹.打开包裹();
            包裹.整理物品();
            包裹.切换到第几页(0);
        重来_:
            var 扔过 = false;
            for (var i = 0; i < 48; i++)
            {
                if (人物.立即小退)
                {
                    人物.立即小退 = false;
                    return 任务名_.重启模拟器_;
                }
                var p = 包裹.包裹点位表[0][i];
                if (包裹.是什么物品(p) == _物品_.空包裹_)
                {
                    goto 结束_;
                }
                if (包裹.是什么物品(p) == _物品_.治疗药水_)
                {
                    扔过 = true;
                    键鼠_.移动鼠标(p);
                    其他_.延迟(其他_.时长_200);
                    键鼠_.左键按下();
                    其他_.延迟(其他_.时长_200);
                    键鼠_.移动鼠标(370, 255);
                    其他_.延迟(其他_.时长_200);
                    键鼠_.左键抬起();
                }
                else if (扔过)
                {
                    goto 结束_;
                }
                其他_.延迟(其他_.时长_400);
            }
            包裹.整理物品();
            goto 重来_;
        结束_:
            包裹.关闭包裹();
            人物.预存的任务 = 任务名_.沙城取药_;
            return 任务名_.捡药_;
        }

        public static 任务名_ 沙城取药(挂机人物_ 人物)
        {
            if (人物.立即小退)
            {
                人物.立即小退 = false;
                return 任务名_.重启模拟器_;
            }
            var 仓库 = 地图_.沙城仓库管理员;
            var 捡药的 = 人物.人物列表.Find(i => i.捡药.HasValue && i.捡药.Value);
            var 数量 = 捡药的 != null ? Math.Min(捡药的.买药取药最大数量, 人物.买药取药最大数量) : 人物.买药取药最大数量;

        _重来_:
            for (var i = 0; i < 数量 / 48; i++)
            {
                var 成功取出 = 仓库.一键取药(人物, 48, out int 库存);
                if (!成功取出)
                {
                    if (库存 < 100)
                    {
                        人物.设置窗口.开启极品拾取及自动捡物();
                        return 任务名_.无_;
                    }
                    仓库.一键存药(人物, out 库存);
                    goto _重来_;
                }
            }
            var 余数 = 数量 % 48;
            if (余数 > 25)
            {
                var 成功取出 = 仓库.一键取药(人物, 余数, out int 库存);
                if (!成功取出)
                {
                    if (库存 < 100)
                    {
                        人物.设置窗口.开启极品拾取及自动捡物();
                        return 任务名_.无_;
                    }
                    仓库.一键存药(人物, out 库存);
                    goto _重来_;
                }
            }

            if (人物.人物列表 != null && 人物.人物列表.Count > 1)
            {
                if (捡药的 != null)
                {
                    人物.预存的任务 = 任务名_.扔药_;
                    return 任务名_.捡药_;
                }
            }
            return 任务名_.扔药_;
        }

        public static 任务名_ 沙城存药(挂机人物_ 人物)
        {
            if (人物.立即小退)
            {
                人物.立即小退 = false;
                return 任务名_.重启模拟器_;
            }
            if (人物.沟通消息 == null) 人物.沟通消息 = new 通知消息_();
            var 捡药消息 = (通知消息_)人物.沟通消息;
            var 仓库 = 地图_.沙城仓库管理员;
            仓库.一键存药(人物, out var 库存);
            if (库存 < 9900)
            {
                var 目标 = new 坐标_(7, 9);
                var p = UI_.连续识别坐标();
                UI_.移动(UI_.根据位置判断方向(p, 目标, out var t, !UI_.切换到走路()), t);
                捡药消息.当前坐标 = p;
                捡药消息.已经准备好 = true;
                return 任务名_.捡药_;
            }
            人物.设置窗口.设置物品为拾取("治疗药水", 物品设置_.贵重_);
            return 任务名_.无_;
        }

        public static 任务名_ 去沙城仓库扔或捡药(挂机人物_ 人物)
        {
            if (人物.无需设置.HasValue && 人物.无需设置.Value)
            {
                人物.连续执行任务 = false;
                return 人物.捡药.HasValue && 人物.捡药.Value ? 任务名_.沙城存药_ : 任务名_.沙城取药_;
            }
            UI_.去拉镖活动.传送(人物, null);
            地图_.城主雕像.去城堡正门(人物);
            var 找到 = UI_.移动到地图内准确位置(地图_.土城去沙城仓库.位置.像素点);
            if (!找到) throw new Exception("未能走到指定位置");
            var i = 0;
            while (UI_.判断角色是否在移动())
            {
                i++;
                其他_.延迟(其他_.时长_400);
                if (i >= 100) throw new Exception("过图失败");
            }
            var 到达 = 地图_.土城去沙城仓库.传送(人物, 地图_.沙城仓库);
            if (!到达) throw new Exception("过图失败");
            if (人物.捡药.HasValue && 人物.捡药.Value)
            {
                UI_.移动(UI_.根据位置判断方向(UI_.连续识别坐标(), new 坐标_(7, 9), out var t, !UI_.切换到走路()), t);
            }
            else
            {
                UI_.移动(UI_.根据位置判断方向(UI_.连续识别坐标(), new 坐标_(7, 11), out var t, !UI_.切换到走路()), t);
            }
            人物.连续执行任务 = false;
            return 人物.捡药.HasValue && 人物.捡药.Value? 任务名_.沙城存药_ : 任务名_.沙城取药_;
        }

        public static 任务名_ 找到NPC(挂机人物_ 人物)
        {
            if (人物.当前要去的点 == null) throw new Exception("没有目标NPC");
            人物.输出("找到NPC: " + 人物.当前要去的点.名称);

            人物.连续执行任务 = true;

            if (人物.当前要去的点.所在地图 == null)
            {
                人物.已经到达位置 = true;
                人物.输出("预存的任务: " + 人物.预存的任务.ToString());
                人物.上个任务名 = 人物.当前任务名;
                人物.当前任务名 = 人物.预存的任务;
                人物.准备动作(false);
                return 人物.预存的任务;
            }
            var 地图名 = UI_.识别地图名();
            if (!地图集_.有地图(地图名))
            {
                UI_.使用回城();
                return 任务名_.找到NPC_;
            }
            else
            {
                var 当前地图 = 地图集_.获取地图(地图名);
                if (当前地图 == 人物.当前要去的点.所在地图) return 任务名_.走到指定坐标点_;
                return 任务名_.走到指定地图_;
            }
        }

        public static 任务名_ 结束买药存药(挂机人物_ 人物)
        {
            人物.输出("完成买药");
            其他_.延迟(其他_.时长_1000);
            return 任务名_.无_;
        }

        public static void 恢复默认值(挂机人物_ 人物)
        {
            人物.已经到达位置栈 = new Stack<bool>();
            人物.当前要去的点栈 = new Stack<地图点_>();
            人物.当前要去的地图栈 = new Stack<地图_>();
            人物.预存的任务栈 = new Stack<任务名_>();
            人物.已经到达位置 = false;
            人物.当前要去的点 = null;
            人物.当前要去的地图 = null;
            人物.预存的任务 = 任务名_.无_;
        }

        public static void 保存现有值(挂机人物_ 人物)
        {
            人物.已经到达位置栈.Push(人物.已经到达位置);
            人物.当前要去的点栈.Push(人物.当前要去的点);
            人物.当前要去的地图栈.Push(人物.当前要去的地图);
            人物.预存的任务栈.Push(人物.预存的任务);
        }

        public static void 恢复上一个值(挂机人物_ 人物)
        {
            人物.已经到达位置 = 人物.已经到达位置栈.Pop();
            人物.当前要去的点 = 人物.当前要去的点栈.Pop();
            人物.当前要去的地图 = 人物.当前要去的地图栈.Pop();
            人物.预存的任务 = 人物.预存的任务栈.Pop();
        }

        public static 任务名_ 海岛存药(挂机人物_ 人物)
        {
            var 地图 = UI_.识别地图名();
            if (地图 != "海岛")
            {
                UI_.去炼狱旋涡.传送(人物, null);
                地图_.炼狱旋涡.传送(人物, 地图_.海岛);
            }
            else
            {
                var 位置 = UI_.连续识别坐标();
                var p = UI_.计算屏幕坐标点位(位置, 地图_.海岛仓库.位置.坐标, out var 方向);
                if (!其他_.点在有效范围内(p))
                {
                    UI_.移动到地图内准确位置(地图_.海岛仓库.位置.像素点);
                    while (UI_.判断角色是否在移动())
                    {
                        其他_.延迟(其他_.时长_1000);
                    }
                }
            }
            var 仓库 = 地图_.海岛仓库;
            仓库.一键存药(人物, out var 库存);
            if (库存 >= 人物.买药库存数量) return 任务名_.结束买药存药_;
            return 任务名_.去沙城买药_;
        }

        public static 任务名_ 去沙城买药(挂机人物_ 人物)
        {
            UI_.去拉镖活动.传送(人物, null);
            地图_.城主雕像.去城堡正门(人物);
            UI_.移动到地图内准确位置(地图_.沙城药商.位置.像素点);
            while (UI_.判断角色是否在移动())
            {
                其他_.延迟(其他_.时长_1000);
            }
            var 沙城药商 = 地图_.沙城药商;
            var 数量 = 人物.买药取药最大数量 + 5 > 120 ? 120 : 人物.买药取药最大数量 + 5;
            沙城药商.购买(人物, new List<物品及数量_> { new 物品及数量_("治疗药水", 数量) });
            return 任务名_.海岛存药_;
        }

        public static 任务名_ 完成所有王城任务(挂机人物_ 人物)
        {
            UI_.打开今日挑战();
            人物.当前任务已完成积分 = 任务积分是否满足(Rectangle.FromLTRB(740, 616, 780, 636));
            if (人物.当前任务已完成积分 < 10)
            {
                if (UI_.获取当前地图() != 地图_.海岛)
                {
                    UI_.去炼狱旋涡.传送(人物, null);
                    地图_.炼狱旋涡.传送(人物, 地图_.海岛);
                }
            }
            // 天玉任务
            点赞任务(人物);
            人物.输出("领取月卡奖励");
            领取月卡奖励();
            人物.当前任务已完成积分 = 任务积分是否满足(Rectangle.FromLTRB(740, 616, 780, 636));
            if (人物.当前任务已完成积分 < 10)
            {
                var 时长 = (11 - 人物.当前任务已完成积分) * 60 * 1000;
                人物.输出("休息: " + (11 - 人物.当前任务已完成积分).ToString() + " 分钟, 完成炼狱任务");
                其他_.延迟(时长);
            }
            人物.输出("领取积分奖励");
            领取积分奖励();
            设置任务记录(人物, "领取奖励");
            return 任务名_.正式开始挂机_;
        }

        public static void 领取月卡奖励()
        {
            键鼠_.左键单击(1027, 83);
            其他_.延迟(其他_.时长_2000);
            键鼠_.左键单击(994, 460);
            其他_.延迟(其他_.时长_1000);
            键鼠_.左键单击(476, 520);
            其他_.延迟(其他_.时长_1000);
            // 关闭窗口
            键鼠_.左键单击(952, 179);
        }

        public static void 领取积分奖励()
        {
            UI_.打开今日挑战();
            其他_.延迟(其他_.时长_2000);
            键鼠_.左键单击(816, 241);
            其他_.延迟(其他_.时长_400);
            键鼠_.左键单击(722, 241);
            其他_.延迟(其他_.时长_400);
            键鼠_.左键单击(627, 241);
            其他_.延迟(其他_.时长_400);
            键鼠_.左键单击(535, 241);
            其他_.延迟(其他_.时长_400);
            键鼠_.左键单击(446, 241);
            其他_.延迟(其他_.时长_400);
            UI_.关闭今日挑战();
            其他_.延迟(其他_.时长_2000);
        }

        public static 任务名_ 点赞任务(挂机人物_ 人物)
        {
            UI_.打开今日挑战();
            人物.当前任务已完成积分 = 任务积分是否满足(Rectangle.FromLTRB(740, 527, 780, 547));
            人物.输出("排行榜任务: " + 人物.当前任务已完成积分.ToString());
            if (人物.当前任务已完成积分 < 5)
            {
                键鼠_.左键单击(1263, 78);
                其他_.延迟(其他_.时长_1000);
                键鼠_.左键单击(843, 271);
                其他_.延迟(其他_.时长_1200);
                键鼠_.左键单击(843, 271);
                其他_.延迟(其他_.时长_1200);
                键鼠_.左键单击(843, 271);
                其他_.延迟(其他_.时长_1200);
                键鼠_.左键单击(843, 271);
                其他_.延迟(其他_.时长_1200);
                键鼠_.左键单击(843, 271);
                其他_.延迟(其他_.时长_1200);
                键鼠_.左键单击(843, 271);
                其他_.延迟(其他_.时长_1200);
            }
            else
            {
                UI_.关闭今日挑战();
            }
            设置任务记录(人物, "点赞任务");
            return 任务名_.正式开始挂机_;
        }

        public static 任务名_ 去海岛打开押镖礼盒(挂机人物_ 人物)
        {
            地图_.炼狱旋涡.传送(人物, 地图_.海岛);
            其他_.延迟(其他_.时长_1000);
            人物.包裹.打开押镖礼盒();
            return 任务名_.正式开始挂机_;
        }

        public static 任务名_ 去海岛等待镖车(挂机人物_ 人物)
        {
            if (人物.镖车监控开始时间 == null)
            {
                人物.镖车监控开始时间 = DateTime.Now;
            }

            var now = DateTime.Now;
            if (now - 人物.镖车监控开始时间 > new TimeSpan(0, 20, 0))
            {
                人物.不领取拉镖礼盒 = true;
                人物.镖车监控线程.镖车监控线程.启动();
                人物.镖车监控线程.镖车监控 += 镖车监控;
                return 任务名_.正式开始挂机_;
            }

            var 当前地图 = UI_.获取当前地图();
            if (当前地图 != 地图_.海岛)
            {
                UI_.去炼狱旋涡.传送(人物, null);
                地图_.炼狱旋涡.传送(人物, 地图_.海岛);
            }
            var 镖车任务 = 图像_.查找文字("立即前往", 29, 112, 115, 143);
            if (镖车任务.X != -1)
            {
                人物.输出("去领取奖品");
                键鼠_.左键单击(其他_.取中心(29, 112, 115, 143));
                其他_.延迟(其他_.时长_5000);

                UI_.鼠标点击屏幕坐标(362, 491, () => 图像_.查找文字("领取奖励", 56, 105, 135, 125).X != -1);
                键鼠_.左键单击(其他_.取中心(56, 105, 135, 125));
                UI_.去炼狱旋涡.传送(人物, null);
                return 任务名_.去海岛打开押镖礼盒_;
            }
            其他_.延迟(其他_.时长_2000);
            return 任务名_.去海岛等待镖车_;
        }

        public static 任务名_ 完成拉镖任务(挂机人物_ 人物)
        {
            var 镖车任务 = 图像_.查找文字("立即前往", 29, 112, 115, 143);
            if (镖车任务.X != -1)
            {
                人物.输出("去领取奖品");
                键鼠_.左键单击(其他_.取中心(29, 112, 115, 143));

                其他_.延迟(其他_.时长_5000);

                UI_.鼠标点击屏幕坐标(362, 491, () => 图像_.查找文字("领取奖励", 56, 105, 135, 125).X != -1);
                键鼠_.左键单击(其他_.取中心(56, 105, 135, 125));
                UI_.去炼狱旋涡.传送(人物, null);
                return 任务名_.去海岛打开押镖礼盒_;
            }

            var 找到 = 战斗_.找到自己的镖车(人物);
            if (!找到)
            {
                找到 = 战斗_.有攻击目标();
                if (找到) return 任务名_.完成拉镖任务_;

                var i = 0;
                do
                {
                    i++;
                    var p = UI_.连续识别坐标();
                    if (UI_.坐标点距离较近(p, new 坐标_(362, 491), 15))
                    {
                        其他_.延迟(其他_.时长_1000);
                        return 任务名_.完成拉镖任务_;
                    }
                    UI_.移动(内部判断方向(p), 2000);
                    其他_.延迟(其他_.时长_200);
                    找到 = 战斗_.找到自己的镖车(人物) || 战斗_.有攻击目标();
                    if (找到)
                    {
                        其他_.延迟(其他_.时长_400);
                        return 任务名_.完成拉镖任务_;
                    }
                    else
                    {
                        镖车任务 = 图像_.查找文字("立即前往", 29, 112, 115, 143);
                        if (镖车任务.X != -1) return 任务名_.完成拉镖任务_;
                    }
                    其他_.延迟(其他_.时长_400);
                }
                while (i < 5);

                其他_.延迟(其他_.时长_1000);

                return 任务名_.去海岛等待镖车_;
            }
            其他_.延迟(其他_.时长_2000);

            return 任务名_.完成拉镖任务_;

            UI_.移动方向_ 内部判断方向(坐标_ 位置)
            {
                if (位置.Y > 800)
                {
                    return UI_.移动方向_.右上_;
                }
                else
               if (位置.Y <= 800 && 位置.Y > 688)
                {
                    return UI_.移动方向_.上_;
                }
                else
               if (位置.Y <= 688 && 位置.Y > 600)
                {
                    return UI_.移动方向_.右上_;
                }
                else
               if (位置.Y <= 600 && 位置.Y > 509)
                {
                    return UI_.移动方向_.上_;
                }
                return UI_.移动方向_.右上_;
            }
        }

        public static bool 镖车监控(挂机人物_ 人物)
        {
            var 镖车任务 = 图像_.查找文字("立即前往", 29, 112, 115, 143);
            if (镖车任务.X != -1)
            {
                人物.输出("关闭立即前往窗口");
                键鼠_.左键单击(516, 55);
            }
            人物.镖车监控线程.镖车监控线程.退出();
            return true;
        }

        public static 任务名_ 押镖任务(挂机人物_ 人物)
        {
            if (!人物.已经到达位置)
            {
                保存现有值(人物);
                人物.当前要去的点 = 地图_.土城镖师;
                人物.预存的任务 = 任务名_.押镖任务_;
                return 任务名_.找到NPC_;
            }
            恢复上一个值(人物);
            var 成功 = 地图_.土城镖师.金币镖车(人物);
            更新任务列表记录(人物);
            设置任务记录(人物, "押镖任务");
            if (人物.不领取拉镖礼盒)
            {
                人物.镖车监控线程.镖车监控线程.启动();
                人物.镖车监控线程.镖车监控 += 镖车监控;
                return 任务名_.正式开始挂机_;
            }
            if (!成功)
            {
                var i = 0;
                do
                {
                    i++;
                    成功 = 战斗_.找到自己的镖车(人物);
                    if (成功) return 任务名_.完成拉镖任务_;
                    人物.技能.使用脱困();
                    UI_.移动(UI_.移动方向_.右上_, 1000);
                    其他_.延迟(其他_.时长_400);
                }
                while (i < 5);
                return 任务名_.去海岛等待镖车_;
            }
            return 任务名_.完成拉镖任务_;
        }

        public static 任务名_ 挖矿任务(挂机人物_ 人物)
        {
            if (!人物.已经到达位置)
            {
                保存现有值(人物);
                人物.当前要去的点 = 地图_.土城铁匠;
                人物.预存的任务 = 任务名_.挖矿任务_;
                人物.当前挖矿索引 = 人物.当前任务已完成积分 / 2;
                return 任务名_.找到NPC_;
            }
            恢复上一个值(人物);
            var n = 人物.当前挖矿索引;
            if (n == 5)
            {
                更新任务列表记录(人物);
                设置任务记录(人物, "挖矿任务");
                UI_.使用回城();
                return 任务名_.正式开始挂机_;
            }
            var 名称组 = new string[] { "铜矿", "铁矿", "黑铁矿石", "银矿", "金矿" };

            地图_.土城铁匠.购买(人物, new List<物品及数量_> { new 物品及数量_(名称组[n], 5) });
            UI_.去挖矿.传送(人物, null);
            UI_.鼠标点击屏幕坐标(new 坐标_(16, 132), () => 图像_.查找文字("在提交矿石前", 56, 128, 167, 148).X != -1);

            if (n == 0)
            {
                键鼠_.左键单击(99, 177);
            }
            else if (n == 1)
            {
                键鼠_.左键单击(243, 177);
            }
            else if (n == 2)
            {
                键鼠_.左键单击(389, 177);
            }
            else if (n == 3)
            {
                键鼠_.左键单击(99, 220);
            }
            else if (n == 4)
            {
                键鼠_.左键单击(247, 220);
            }
            其他_.延迟(其他_.时长_1000);
            键鼠_.左键单击(519, 55);
            var 关闭 = 其他_.循环判断(() => !(图像_.查找文字("在提交矿石前", 56, 128, 167, 148).X != -1), 5);
            if (!关闭) throw new Exception("没能关闭提交窗口");
            if (n == 4)
            {
                UI_.开启内挂(true);
                更新任务列表记录(人物);
                设置任务记录(人物, "挖矿任务");
                人物.当前挖矿索引 = 0;
                return 任务名_.正式开始挂机_;
            }
            else
            {
                人物.已经到达位置 = false;
                UI_.打开今日挑战();
                人物.当前任务已完成积分 = 任务积分是否满足(Rectangle.FromLTRB(740, 435, 780, 455));
                UI_.去炼狱旋涡.传送(人物, null);
                return 任务名_.挖矿任务_;
            }
        }

        public static 任务名_ 骑兵任务(挂机人物_ 人物)
        {
            var 马倌 = 地图_.马倌;
            if (!人物.已经到达位置)
            {
                保存现有值(人物);
                人物.当前要去的点 = 马倌;
                人物.预存的任务 = 任务名_.骑兵任务_;
                return 任务名_.找到NPC_;
            }
            恢复上一个值(人物);
            马倌.去骑兵竞技(人物);
            更新任务列表记录(人物);
            设置任务记录(人物, "骑兵任务");
            return 任务名_.正式开始挂机_;
        }

        public static 任务名_ 完成当前王城任务(挂机人物_ 人物)
        {
            var 内容 = 图像_.查找文字("江湖公告", 171, 67, 251, 89);
            if (内容.X != -1)
            {
                return 任务名_.王城任务_;
            }

            var 当前地图 = UI_.获取当前地图();

            if (当前地图.分类 != 人物.当前王城任务地图分类)
            {
                return 去王城任务地图(人物);
            }

            UI_.开启内挂();

            if (人物.任务关注怪物.Count > 0)
            {
                var 持续 = true;
                var i = 0;
                while (持续 && i < 10)
                {
                    i++;
                    持续 = !战斗_.监控任务专注怪物列表(人物, out var 专注怪物);
                    if (专注怪物 != null)
                    {
                        键鼠_.左键单击(专注怪物.点位);
                        其他_.延迟(其他_.时长_2000);
                        return 任务名_.完成当前王城任务_;
                    }
                    其他_.延迟(其他_.时长_2000);
                    UI_.使用快捷随机(人物);
                }
                return 任务名_.完成当前王城任务_;
            }
            else
            {
                var i = 0;
                while (i < 5 && !战斗_.快速监控怪物列表())
                {
                    if (当前地图.分类 == 地图分类_.机关洞_ &&
                        (当前地图 == 地图_.角斗场 ||
                        当前地图 == 地图_.中枢大殿 ||
                        当前地图 == 地图_.战斗广场一 ||
                        当前地图 == 地图_.战斗广场二 ||
                        当前地图 == 地图_.战斗广场三))
                    {
                        return 点击传送();
                    }
                    else
                    if (当前地图.分类 == 地图分类_.逆魔古刹_ && 当前地图 == 地图_.讲经堂)
                    {
                        return 点击传送();
                    }
                    else
                    if (当前地图.分类 == 地图分类_.蛇魔谷_ && 当前地图 == 地图_.盘蛇道)
                    {
                        return 点击传送();
                    }
                    i++;
                    其他_.延迟(其他_.时长_2000);
                    UI_.使用快捷随机(人物);
                }
                其他_.延迟(其他_.时长_1000);
                return 任务名_.完成当前王城任务_;
            }

            任务名_ 点击传送()
            {
                UI_.去王城任务.传送(人物, null);
                键鼠_.左键单击(123, 78);
                其他_.延迟(其他_.时长_1000);
                UI_.开启内挂(/*不报错*/ true);
                var 当前到达的地图 = UI_.识别地图名();
                if (当前到达的地图 != "跃马大平原")
                {
                    return 任务名_.完成当前王城任务_;
                }
                其他_.延迟(其他_.时长_1000);
                当前到达的地图 = UI_.识别地图名();
                if (当前到达的地图 != "跃马大平原")
                {
                    return 任务名_.完成当前王城任务_;
                }
                throw new Exception("王城任务错误");
            }
        }

        public static 任务名_ 去王城任务地图(挂机人物_ 人物)
        {
            var 地图 = 图像_.识别文字(47, 67, 197, 91);
            if (地图 != "" && 地图.Contains("在"))
            {
                地图 = 地图.Replace(" ", "").Substring(1);
                var index = 地图.IndexOf("系");
                if (index != -1)
                {
                    地图 = 地图.Substring(0, index);
                    if (地图.Contains("将军"))
                    {
                        人物.当前王城任务地图分类 = 地图分类_.将军坟_;
                    }
                    else if (地图.Contains("机关"))
                    {
                        人物.当前王城任务地图分类 = 地图分类_.机关洞_;
                    }
                    else if (地图.Contains("通天"))
                    {
                        人物.当前王城任务地图分类 = 地图分类_.通天塔_;
                    }
                    else if (地图.Contains("禁地"))
                    {
                        人物.当前王城任务地图分类 = 地图分类_.禁地_;
                    }
                    else if (地图.Contains("逆魔"))
                    {
                        人物.当前王城任务地图分类 = 地图分类_.逆魔古刹_;
                    }
                    else if (地图.Contains("蛇"))
                    {
                        人物.当前王城任务地图分类 = 地图分类_.蛇魔谷_;
                    }
                    if (人物.当前军机 == 0 && 地图.Contains("将军") || 人物.当前军机 == 1 && 地图.Contains("机关"))
                    {
                        return 任务名_.去交军机地图_;
                    }
                    人物.输出("当前任务地图是: " + 地图 + " 系列");
                }
            }
            else if (地图 != "" && 地图.Contains("击杀"))
            {
                if (地图.Contains("白"))
                {
                    人物.输出("当前任务是: 在 蛇魔谷 击杀1只白蛇妖");
                    if (!人物.任务关注怪物.ContainsKey("白蛇妖"))
                    {
                        人物.任务关注怪物.Add("白蛇妖", 怪物列表_.获取怪物("白蛇妖"));
                    }
                    人物.当前王城任务地图分类 = 地图分类_.蛇魔谷_;
#if _发行_
                    if (人物.当前军机 == 2)
                    {
                        return 任务名_.完成当前王城任务_;
                    }
#endif
                }
                else if (地图.Contains("幽"))
                {
                    人物.输出("当前任务是: 在 禁地 击杀1只幽灵虫母");

                    if (!人物.任务关注怪物.ContainsKey("幽灵虫母"))
                    {
                        人物.任务关注怪物.Add("幽灵虫母", 怪物列表_.获取怪物("幽灵虫母"));
                    }
                    人物.当前王城任务地图分类 = 地图分类_.禁地_;
#if _发行_
                    if (人物.当前军机 == 4)
                    {
                        return 任务名_.完成当前王城任务_;
                    }
#endif
                }
                else if (地图.Contains("金"))
                {
                    人物.输出("当前任务是: 在 机关洞 击杀1只金刚人");

                    if (!人物.任务关注怪物.ContainsKey("金刚人"))
                    {
                        人物.任务关注怪物.Add("金刚人", 怪物列表_.获取怪物("金刚人"));
                    }
                    人物.当前王城任务地图分类 = 地图分类_.机关洞_;
#if _发行_
                    if (人物.当前军机 == 1)
                    {
                        return 任务名_.完成当前王城任务_;
                    }
#endif
                }
                else
                {
                    人物.输出("未能准确判断任务九要求击杀的怪物");
                }
            }
            else if (地图 != "" && 地图.Contains("收集"))
            {
                if (地图.Contains("叶子"))
                {
                    人物.输出("收集5个叶子");
                }
                else
                if (地图.Contains("果实"))
                {
                    人物.输出("收集5个果实");
                }
                else
                if (地图.Contains("牙齿"))
                {
                    人物.输出("收集5个牙齿");
                }
                else
                if (地图.Contains("蟾酥"))
                {
                    人物.输出("收集5个蟾酥");
                }
                else
                if (地图.Contains("蛆卵") || 地图.Contains("蝎尾"))
                {
                    人物.输出("收集5个蛆卵或蝎尾");
                }
                else
                if (地图.Contains("木材"))
                {
                    人物.输出("收集5个木材");
                }
                else
                if (地图.Contains("金矿"))
                {
                    人物.输出("收集3个金矿");
                }
                else
                if (地图.Contains("银矿"))
                {
                    人物.输出("收集5个银矿");
                }
                else
                if (地图.Contains("天玉"))
                {
                    人物.输出("收集10个天玉");
                }
                else
                if (地图.Contains("祝福"))
                {
                    人物.输出("收集3个祝福神油");
                }
                else
                if (地图.Contains("降妖") || 地图.Contains("珊瑚"))
                {
                    人物.输出("收集1个降妖, 1个珊瑚");
                }
                else
                if (地图.Contains("大关") || 地图.Contains("方天") || 地图.Contains("狼牙"))
                {
                    人物.输出("收集3件将军武器");
                }
                // 这里判断是收集的啥
                return 任务名_.正式开始挂机_;
            }
            else
            {
                人物.输出("未能准确识别任务地图");
            }
            键鼠_.左键单击(123, 78);
            其他_.延迟(其他_.时长_1000);
            UI_.开启内挂(/*不报错*/ true);
            var 当前到达的地图 = UI_.获取当前地图();
            if (当前到达的地图.分类 == 人物.当前王城任务地图分类)
            {
                return 任务名_.完成当前王城任务_;
            }
            throw new Exception("王城任务错误");
        }

        public static 任务名_ 王城任务(挂机人物_ 人物)
        {
            var 王城 = 地图_.王城公告牌;
            var 有任务没完成 = 王城.有未完成的任务();
            if (有任务没完成 == 王城公告牌_.完成情况_.有未完成击杀)
            {
                人物.输出("去任务地图");
                return 去王城任务地图(人物);
            }

            var 接受完任务 = 王城.去王城任务(人物, 有任务没完成);
            if (接受完任务)
            {
                return 去王城任务地图(人物);
            }
            更新任务列表记录(人物);
            设置任务记录(人物, "王城任务");
            return 任务名_.正式开始挂机_;
        }

        public static 任务名_ 论武任务(挂机人物_ 人物)
        {
            var 教头 = 地图_.武馆教头;
            if (!人物.已经到达位置)
            {
                保存现有值(人物);
                人物.当前要去的点 = 教头;
                人物.预存的任务 = 任务名_.论武任务_;
                return 任务名_.找到NPC_;
            }
            恢复上一个值(人物);
            var 到达 = 教头.去论武任务(人物);
            if (到达)
            {
                手动论武战斗(人物);
            }
            更新任务列表记录(人物);
            设置任务记录(人物, "论武任务");
            return 任务名_.正式开始挂机_;
        }

        public static 任务名_ 完成声望任务(挂机人物_ 人物)
        {
            var 有弹出确定 = 图像_.查找文字(615, 429, 665, 451, (string s) => s.Contains("确定"));
            if (有弹出确定.X != -1)
            {
                人物.输出("已经完成当前任务");
                键鼠_.左键单击(其他_.取中心(615, 429, 665, 451));
                其他_.延迟(其他_.时长_1000);
                return 任务名_.正式开始挂机_;
            }
            var 地图 = UI_.识别地图名();
            if (地图 == "跃马大平原")
            {
                return 任务名_.正式开始挂机_;
            }
            其他_.延迟(其他_.时长_2000);
            return 任务名_.完成声望任务_;
        }

        public static 任务名_ 声望任务(挂机人物_ 人物)
        {
            var 做完了 = 人物.当前任务已完成积分;
            人物.输出("声望任务目前积分: " + 做完了.ToString());
            if (做完了 != 9)
            {
                var 老者 = 地图_.声望老人;
                if (!人物.已经到达位置)
                {
                    保存现有值(人物);
                    人物.当前要去的点 = 老者;
                    人物.预存的任务 = 任务名_.声望任务_;
                    return 任务名_.找到NPC_;
                }
                恢复上一个值(人物);
                UI_.关闭今日挑战();
                var i = 做完了 / 3;
                if (i == 0)
                {
                    var 到达 = 老者.去帮助矿工(人物);
                    if (到达)
                    {
                        UI_.开启内挂();
                        return 任务名_.完成声望任务_;
                    }
                }
                else if (i == 1)
                {
                    var 到达 = 老者.去帮助奸商(人物);
                    if (到达)
                    {
                        UI_.开启内挂();
                        return 任务名_.完成声望任务_;
                    }
                }
                else
                {
                    var 到达 = 老者.去帮助将军(人物);
                    if (到达)
                    {
                        UI_.开启内挂();
                        return 任务名_.完成声望任务_;
                    }
                }
            }
            更新任务列表记录(人物);
            设置任务记录(人物, "声望任务");
            return 任务名_.正式开始挂机_;
        }

        public static Point 判断任务列表(挂机人物_ 人物)
        {
            Rectangle[] 列表范围 = new Rectangle[]
            {
                Rectangle.FromLTRB(104, 59, 179, 79),
                Rectangle.FromLTRB(104, 80, 179, 100),
                Rectangle.FromLTRB(104, 101, 179, 121),
                Rectangle.FromLTRB(104, 122, 179, 152),
                Rectangle.FromLTRB(104, 153, 179, 173),
                Rectangle.FromLTRB(104, 174, 179, 194),
                Rectangle.FromLTRB(104, 195, 179, 215),
            };

            Point[] 点表 = new Point[]
            {
                new Point (60, 70),
                new Point (60, 90),
                new Point (60, 112),
                new Point (60, 138),
                new Point (60, 161),
                new Point (60, 184),
                new Point (60, 200)
            };

            for (var i = 0; i < 列表范围.Length; i++)
            {
                var 当前行 = 图像_.识别文字(列表范围[i]).Trim();
                var 转换完内容 = 转换内容(当前行);
                if (人物.指定接受的军机任务 == 转换完内容)
                {
                    return 点表[i];
                }
            }
            return new Point(-1, -1);

            string 转换内容(string 内容)
            {
                if (内容.Contains("高智商"))
                {
                    return "高智商的怪物把守着邪恶的魔城,他们的各阶层统帅谙熟排兵布阵";
                }
                else if (内容.Contains("城是"))
                {
                    return "魔城是邪恶的源头, 邪恶之力控制人类使其成为魔王的傀儡";
                }
                else if (内容.Contains("地下迷"))
                {
                    return "地下迷宫和狭窄的山谷是魔城的天然屏障,军队会受到重创";
                }
                else if (内容.Contains("城高"))
                {
                    return "魔城高大且坚不可摧,唯一的入口由巨大的兽兵日夜把守";
                }
                return "";
            }
        }

        public static 任务名_ 交军机任务(挂机人物_ 人物)
        {
            var 地图名 = UI_.识别地图名();
            if (地图名 == "将军坟三层")
            {
                if (!人物.已经到达位置)
                {
                    保存现有值(人物);
                    人物.当前要去的点 = new 地图点_(new 点及坐标_(new Point(370, 373), new 坐标_(102, 130)), 点属性_.无_, 地图_.将军坟三层);
                    人物.预存的任务 = 任务名_.交军机任务_;
                    return 任务名_.走到指定坐标点_;
                }
                恢复上一个值(人物);
                return 交任务(0, 100, 128);
            }
            if (地图名 == "角斗场")
            {
                if (!人物.已经到达位置)
                {
                    保存现有值(人物);
                    人物.当前要去的点 = new 地图点_(new 点及坐标_(new Point(564, 432), new 坐标_(130, 122)), 点属性_.无_, 地图_.角斗场);
                    人物.预存的任务 = 任务名_.交军机任务_;
                    return 任务名_.走到指定坐标点_;
                }
                恢复上一个值(人物);
                return 交任务(1, 130, 119);
            }
            if (地图名 == "五蛇殿")
            {
                UI_.开启内挂();
                return 任务名_.完成当前王城任务_;
            }
            if (地图名 == "逆魔古刹三层")
            {
                UI_.开启内挂();
                return 任务名_.完成当前王城任务_;
            }
            if (地图名 == "生死门")
            {
                UI_.开启内挂();
                return 任务名_.完成当前王城任务_;
            }
            if (地图名 == "八仙纵横")
            {
                UI_.开启内挂();
                return 任务名_.完成当前王城任务_;
            }
            if (地图名 == "地下魔域四层")
            {
                UI_.开启内挂();
                return 任务名_.完成当前王城任务_;
            }
            return 任务名_.无_;

            任务名_ 交任务(int 任务序号, int X, int Y)
            {
                Rectangle[] 位置组 = new Rectangle[] {

                Rectangle.FromLTRB(27, 140, 138, 160),
                Rectangle.FromLTRB(27, 162, 138, 182)
                };

                var 范围 = 位置组[任务序号];
                UI_.鼠标点击屏幕坐标(X, Y, () => 图像_.查找文字(范围, s => s.Contains("传达")).X != -1);

                键鼠_.左键单击(其他_.取中心(范围));
                Point p = new Point(-1, -1);
                其他_.循环判断(() =>
                {
                    p = 判断任务列表(人物);
                    return p.X != -1;
                });
                if (p.X == -1) return 任务名_.完成当前王城任务_;
                人物.输出("提交军机任务");
                键鼠_.左键单击(p);
                var 完成 = 其他_.循环判断(() => 图像_.查找文字(27, 139, 139, 158, s => s.Contains("继续")).X != -1);
                if (完成)
                {
                    键鼠_.左键单击(其他_.取中心(27, 139, 139, 158));
                    UI_.开启内挂();
                    人物.当前军机 = 任务序号 + 1;
                    return 任务名_.完成当前王城任务_;
                }
                throw new Exception("交军机任务失败");
            }
        }

        public static string 获取军机地图名(挂机人物_ 人物)
        {
            if (人物.当前军机 == -1) return "无_";
            string[] 地图名组 = new string[] { "将军坟三层", "角斗场", "五蛇殿", "逆魔古刹三层", "生死门", "八仙纵横", "地下魔域四层" };
            return 地图名组[人物.当前军机];
        }

        public static 任务名_ 去交军机地图(挂机人物_ 人物)
        {
            var i = 0;
            do
            {
                i++;
                键鼠_.左键单击(123, 78);
                其他_.延迟(其他_.时长_2000);
                if (!UI_.判断地图名(获取军机地图名(人物), 2))
                {
                    UI_.使用回城();
                }
                else
                {
                    return 任务名_.交军机任务_;
                }
                if (i > 10)
                {
                    UI_.开启内挂();
                    return 任务名_.完成当前王城任务_;
                }
            }
            while (true);
        }

        public static bool 放弃军机任务(挂机人物_ 人物)
        {
            var 找到 = UI_.鼠标点击屏幕坐标(177, 810, () => 图像_.查找文字("矿区入口", 55, 106, 136, 126).X != -1);
            if (!找到) return false;
            人物.输出("点击军机令任务");
            键鼠_.左键单击(530, 320);
            找到 = 其他_.循环判断(() => 图像_.查找文字("接受任务", 54, 175, 134, 196).X != -1);
            if (!找到) return false;
            键鼠_.左键单击(94, 185);
            找到 = 其他_.循环判断(() => 图像_.查找文字("放弃任务", 57, 107, 133, 129).X != -1);
            if (!找到) return false;
            键鼠_.左键单击(94, 117);
            找到 = 其他_.循环判断(() => 图像_.查找文字("放弃", 57, 107, 133, 129).X != -1);
            if (!找到) return false;
            键鼠_.左键单击(94, 117);
            找到 = 其他_.循环判断(() => 图像_.查找文字("离开", 57, 107, 133, 129).X != -1);
            键鼠_.左键单击(94, 117);
            return true;
        }

        public static bool 接受军机任务(挂机人物_ 人物)
        {
            var 当前地图 = UI_.获取当前地图();
            if (当前地图 != 地图_.跃马大平原 || UI_.坐标点距离较近(UI_.连续识别坐标(), new 坐标_(177, 810), 8))
            {
                UI_.去马倌.传送(人物, null);
            }

            UI_.鼠标点击屏幕坐标(177, 810, () => 图像_.查找文字("矿区入口", 55, 106, 136, 126).X != -1);
            人物.输出("点击军机令任务");
            键鼠_.左键单击(530, 320);

            var 找到 = 其他_.循环判断(() => 图像_.查找文字("接受任务", 54, 175, 134, 196).X != -1);
            if (!找到) return false;

            键鼠_.左键单击(94, 185);
            找到 = 其他_.循环判断(() => 图像_.查找文字(26, 61, 193, 82, s => s.Contains("你已完成") || s.Contains("你有任务")).X != -1);
            if (找到)
            {
                键鼠_.左键单击(518, 56);
                其他_.延迟(其他_.时长_1000);
                var 值 = CultureInfo.CurrentCulture.Calendar.
                        GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                人物.输出("本周的已经完成, 设置记录: " + 值);
                设置任务记录(人物, "军机任务", 值.ToString());
                return true;
            }

            找到 = 其他_.循环判断(() => 图像_.查找文字(42, 188, 118, 210, s => s.Contains("准备好了")).X != -1);
            键鼠_.左键单击(118, 198);
            var 内容 = "";
            其他_.循环判断(() =>
            {
                内容 = 图像_.识别文字(27, 81, 120, 104);
                return 内容 != "";
            });

            找到 = 其他_.循环判断(() => 图像_.查找文字(85, 220, 128, 240, s => s.Contains("离开")).X != -1);
            if (!找到) return false;

            键鼠_.左键单击(118, 230);

            人物.输出("本次军机: " + 内容);

            if (内容.Contains("高智商"))
            {
                return 人物.指定接受的军机任务 == "高智商的怪物把守着邪恶的魔城,他们的各阶层统帅谙熟排兵布阵";
            }
            else if (内容.Contains("城是"))
            {
                return 人物.指定接受的军机任务 == "魔城是邪恶的源头, 邪恶之力控制人类使其成为魔王的傀儡";
            }
            else if (内容.Contains("地下迷"))
            {
                return 人物.指定接受的军机任务 == "地下迷宫和狭窄的山谷是魔城的天然屏障,军队会受到重创";
            }
            else if (内容.Contains("城高"))
            {
                return 人物.指定接受的军机任务 == "魔城高大且坚不可摧,唯一的入口由巨大的兽兵日夜把守";
            }
            else
            {
                人物.输出("没能准确识别军机任务: " + 内容);
                return false;
            }
        }

        public static 任务名_ 军机令任务(挂机人物_ 人物)
        {
            if (UI_.已经接了军机任务(out var 军机))
            {
                人物.输出("放弃当前军机");
                其他_.循环判断(() =>
                {
                    return 放弃军机任务(人物);
                }, 50);
                return 任务名_.军机令任务_;
            }
            var 成功 = 接受军机任务(人物);
            if (!成功)
            {
                return 任务名_.军机令任务_;
            }
            return 任务名_.正式开始挂机_;
        }

        public static void 手动论武战斗(挂机人物_ 人物)
        {
            // 战斗
            var 已经攻击 = 0;
            var 已经施毒 = !人物.技能.可以施毒;
            var 开始时间 = DateTime.Now;
            var 结束时间 = DateTime.Now;
            while ((结束时间 - 开始时间).TotalMilliseconds < 1000 * 60 * 15)
            {
                if (战斗_.快速监控怪物列表())
                {
                    if (人物.职业 == "道士")
                    {
                        if (已经施毒)
                        {
                            if (!人物.技能.可以施毒)
                            {
                                if (!战斗_.有攻击目标())
                                {
                                    人物.输出("主技能攻击");
                                    人物.技能.使用主攻();
                                }
                            }
                            else if (已经攻击 < 5)
                            {
                                人物.输出("主技能攻击");
                                人物.技能.使用主攻();
                                已经攻击++;
                            }
                            已经施毒 = 战斗_.有红绿毒();
                        }
                        else if (!已经施毒)
                        {
                            人物.输出("辅技能攻击");
                            人物.技能.使用辅攻();
                            已经施毒 = 战斗_.有红绿毒();
                            已经攻击 = 0;
                        }
                    }
                    else
                    {
                        if (!战斗_.有攻击目标())
                        {
                            人物.输出("主技能攻击");
                            人物.技能.使用主攻();
                        }
                    }
                }
                else
                {
                    var 有弹出确定 = 图像_.查找文字(628, 432, 678, 454, (string s) => s.Contains("确定"));
                    if (有弹出确定.X != -1)
                    {
                        人物.输出("已经完成当前任务");
                        键鼠_.左键单击(其他_.取中心(628, 432, 678, 454));
                        其他_.延迟(其他_.时长_1000);
                        return;
                    }
                    人物.输出("目标较远, 等待 10秒");
                    其他_.延迟(其他_.时长_1000);
                }
            }
            return;
        }

        public static 任务名_ 手动战斗(挂机人物_ 人物)
        {
            // 战斗
            var 已经攻击 = 0;
            var 已经施毒 = !人物.技能.可以施毒;
            while (!其他_.cts.IsCancellationRequested)
            {
                if (战斗_.快速监控怪物列表())
                {
                    if (人物.职业 == "道士")
                    {
                        if (已经施毒)
                        {
                            if (!人物.技能.可以施毒)
                            {
                                if (!战斗_.有攻击目标())
                                {
                                    人物.输出("主技能攻击");
                                    人物.技能.使用主攻();
                                }
                                else
                                {
                                    操作_.捡取物品(人物);
                                }
                            }
                            else if (已经攻击 < 5)
                            {
                                人物.输出("主技能攻击");
                                人物.技能.使用主攻();
                                已经攻击++;
                            }
                            已经施毒 = 战斗_.有红绿毒();
                        }
                        else if (!已经施毒)
                        {
                            人物.输出("辅技能攻击");
                            人物.技能.使用辅攻();
                            已经施毒 = 战斗_.有红绿毒();
                            if (已经施毒) 操作_.捡取物品(人物);
                            已经攻击 = 0;
                        }
                        if (战斗_.发现物品或怪物() == 发现物品或怪物_.发现物品_)
                        {
                            已经攻击 = 0;
                            已经施毒 = !人物.技能.可以施毒;
                            var 还有物品 = false;
                            var i = 0;
                            do
                            {
                                i++;
                                UI_.点击捡物();
                                人物.输出("捡取 " + i + " 次");
                                还有物品 = 其他_.循环判断(() => 战斗_.发现物品或怪物() != 发现物品或怪物_.无_);
                            }
                            while (还有物品);
                        }
                    }
                    else
                    {
                        if (!战斗_.有攻击目标())
                        {
                            人物.输出("主技能攻击");
                            人物.技能.使用主攻();
                        }
                    }
                }
                else
                {
                    操作_.捡取物品(人物);
                    UI_.使用随机(人物);
                    其他_.延迟(其他_.时长_100);
                }
            }
            return 任务名_.无_;
        }

        public static 任务名_ 开始战斗(挂机人物_ 人物)
        {
            人物.连续执行任务 = false;
            人物.输出("开始战斗");
            var 挂机地图 = 地图集_.获取地图(人物.挂机地图名);
            if ((挂机地图.属性 & 地图属性_.不可内挂_) == 0)
            {
                // 点击挂机
                UI_.开启内挂();
                人物.开始挂机时间 = DateTime.Now;
                return 任务名_.监控挂机状态_;
            }
            else
            {
                return 手动战斗(人物);
            }
        }

        public static bool 监控出售声望信息(挂机人物_ 人物, 聊天分类及内容_[] 内容)
        {
            var s0 = 内容[0];
            var s1 = 内容[1];
            if (s0.内容.Contains("声望") || s1.内容.Contains("声望"))
            {
                var n1 = Regex.Replace(s0.内容, "[^0-9]", "");
                if (n1 != "")
                {
                    其他_.尝试编译数字(n1);
                    人物.输出("发现有人出售: " + n1.ToString() + " 个声望");
                }
                else
                {
                    n1 = Regex.Replace(s1.内容, "[^0-9]", "");
                    if (n1 != "")
                    {
                        其他_.尝试编译数字(n1);
                        人物.输出("发现有人出售: " + n1.ToString() + " 个声望");
                    }
                }
                材料行_.购买声望();
            }
            return true;
        }

        public static 任务名_ 专注材料行购买(挂机人物_ 人物)
        {
            材料行_.打开材料行();
            其他_.延迟(其他_.时长_1000);
            人物.聊天监控.聊天事件处理 = 监控出售声望信息;
            人物.聊天监控.聊天监控线程.启动();
            材料行_.购买声望();
            return 任务名_.无_;
        }

        public static 任务名_ 走到指定地图(挂机人物_ 人物)
        {
            if (人物.已经到达位置)
            {
                var 当前传送 = (快捷传送_)人物.当前要去的点;
                人物.输出("开始过图: " + 当前传送.名称);
                var 到达 = 当前传送.传送(人物, 人物.当前要去的地图);
                恢复上一个值(人物);
                if (!到达)
                {
                    人物.输出("过图失败: " + 当前传送.名称);
                    人物.临时过图路径.Clear();
                    人物.输出("清空路径重新计算");
                    return 任务名_.走到指定地图_;
                }
                人物.输出("完成过图: " + 当前传送.名称);
                return 人物.临时过图路径.Count == 0 ? 任务名_.走到指定坐标点_ : 任务名_.走到指定地图_;
            }
            else
            {
                if (人物.临时过图路径.Count == 0)
                {
                    var 目标地图 = 人物.当前要去的点.所在地图;
                    var 地图名 = UI_.识别地图名();
                    if (!地图集_.有地图(地图名))
                    {
                        UI_.使用回城();
                        if (目标地图 == 地图_.跃马大平原) return 任务名_.走到指定坐标点_;
                        return 任务名_.走到指定地图_;
                    }
                    人物.输出("计算临时过图路径");
                    var 当前地图 = 地图集_.获取地图(地图名);
                    if (目标地图 == null) throw new Exception("未知地图错误");
                    人物.临时过图路径 = 路径计算_.计算(当前地图, 目标地图, 人物);
                    if (人物.临时过图路径.Count == 0) return 任务名_.已经到达指定地点_;
                }
                var 当前门点 = 人物.临时过图路径.Pop();
                保存现有值(人物);
                人物.当前要去的点 = 当前门点.传送门;
                人物.当前要去的地图 = 当前门点.目标;
                人物.预存的任务 = 任务名_.走到指定地图_;
                if (当前门点.传送门.所在地图 != null) return 任务名_.找到NPC_;

                return 任务名_.已经到达指定地点_;
            }
        }

        public static 任务名_ 去挂机地图(挂机人物_ 人物)
        {
            var 目标地图 = 地图集_.获取地图(人物.挂机地图名);
            var 地图名 = UI_.识别地图名();
            if (!地图集_.有地图(地图名))
            {
                UI_.使用回城();
                return 任务名_.去挂机地图_;
            }
            var 当前地图 = 地图集_.获取地图(地图名);
            if (目标地图 == 当前地图 && !人物.已经到达位置)
            {
                return 开始战斗(人物);
            }

            if (人物.过图路径.Count == 0)
            {
                人物.输出("计算过图路径");
                if (目标地图 == null)
                {
                    人物.输出("这会错误");
                }
                人物.过图路径 = 路径计算_.计算(当前地图, 目标地图, 人物);
            }
            人物.输出("还需要完成: " + 人物.过图路径.Count + " 个路径点.");

            var 路径组 = 人物.过图路径.ToArray();

            for (var i = 0; i < 路径组.Length; i++)
            {
                人物.输出("路径" + (i + 1).ToString() + ": " + 路径组[i].传送门.名称);
            }

            if (!人物.已经到达位置)
            {
                var 当前门点 = 人物.过图路径.Pop();
                保存现有值(人物);
                人物.当前要去的点 = 当前门点.传送门;
                人物.当前要去的地图 = 当前门点.目标;
                人物.预存的任务 = 任务名_.去挂机地图_;
                return 任务名_.找到NPC_;
            }
            var 当前传送 = (快捷传送_)人物.当前要去的点;
            人物.输出("开始过图: " + 当前传送.名称);
            var 到达 = 当前传送.传送(人物, 人物.当前要去的地图);
            恢复上一个值(人物);
            if (!到达)
            {
                人物.输出("过图失败: " + 当前传送.名称);
                人物.过图路径.Clear();
                return 任务名_.去挂机地图_;
            }
            人物.输出("完成过图: " + 当前传送.名称);
            if (人物.过图路径.Count == 0)
            {
                return 开始战斗(人物);
            }
            return 任务名_.去挂机地图_;
        }

        public static 任务名_ 设置初始值(挂机人物_ 人物)
        {
            if (人物.挂机地图名 == "当前地图" && 人物.定点挂机.HasValue && 人物.定点挂机.Value)
            {
                人物.已经初始设置 = true;
                人物.挂机地图名 = UI_.识别地图名();
                return 任务名_.守点挂机_;
            }
            if (人物.姓名 == "" || 人物.职业 == "" || 人物.等级 == 0)
            {
                人物.输出("小退操作");
                人物.设置窗口.小退操作();
                人物.输出("小退操作完成");
                return 操作_.判断人物及职业等级(人物);
            }

            var 地图 = UI_.识别地图名();
            if (地图 == "小黑屋")
            {
                if (人物.二级密码 != "")
                {
                    var 小黑屋安全员 = new 账号安全员_();
                    小黑屋安全员.传送(人物, null);
                }
                else
                {
                    关闭模拟器(人物);
                    return 任务名_.无_;
                }
            }

            if (人物.特殊挂机.HasValue && 人物.特殊挂机.Value && 人物.材料行购买.HasValue && 人物.材料行购买.Value && 人物.材料行购买物品名 != "无")
            {
                if (地图 != "海岛")
                {
                    UI_.去炼狱旋涡.传送(人物, null);
                    地图_.炼狱旋涡.传送(人物, 地图_.海岛);
                }
                return 任务名_.专注材料行购买_;
            }

            if (人物.特殊挂机.HasValue && 人物.特殊挂机.Value && (人物.买药.HasValue && 人物.买药.Value || 人物.捡药.HasValue && 人物.捡药.Value || 人物.扔药.HasValue && 人物.扔药.Value))
            {
                if (人物.无需设置.HasValue && 人物.无需设置.Value && 地图 == "仓库")
                {
                    return 任务名_.正式开始挂机_;
                }
                if (地图 != "海岛" && 地图 != "仓库")
                {
                    UI_.去炼狱旋涡.传送(人物, null);
                    地图_.炼狱旋涡.传送(人物, 地图_.海岛);
                }
                UI_.设置收缩材料行();
                人物.宠物.宠物休息();
                return 任务名_.正式开始挂机_;
            }

            if (!人物.已经初始设置)
            {
                if (地图 != "海岛")
                {
                    UI_.去炼狱旋涡.传送(人物, null);
                    地图_.炼狱旋涡.传送(人物, 地图_.海岛);
                }
                人物.输出("进行初始设置");
                if (!人物.已经初始设置)
                {
                    人物.设置窗口.确保游戏基本设置正确();
                }
                人物.已经初始设置 = true;
            }
            UI_.设置收缩材料行();
            玩家怪物列表_.设置怪物列表();
            人物.攻击模式.切换模式(模式_.和平_);
            其他_.延迟(其他_.时长_1000);
            if (人物.预存的任务 != 任务名_.无_)
            {
                return 人物.预存的任务;
            }
            return 任务名_.正式开始挂机_;
        }

        private static bool 是可以从商人购买的物品(string 名称)
        {
            List<string> 列表 = new List<string> { "特级金创药包", "特级魔法药包" };

            return 列表.Contains(名称);
        }

        private static bool 是可以从元宝商城购买的物品(string 名称)
        {
            List<string> 列表 = new List<string> { "金条", "金砖" };

            return 列表.Contains(名称);
        }

        private static bool 是可以从金币商城购买的物品(string 名称)
        {
            List<string> 列表 = new List<string> {
             "回城石", "随机神石", "冰泉圣水", "道尊神符", "道尊红毒", "道尊绿毒"
            };
            return 列表.Contains(名称);
        }

        public static 任务名_ 补充物品(挂机人物_ 人物)
        {
            var 仓库 = 地图_.海岛仓库;
            if (!人物.已经到达位置)
            {
                人物.输出("去补充包裹");
                保存现有值(人物);
                人物.当前要去的点 = 仓库;
                人物.预存的任务 = 任务名_.补充物品_;
                return 任务名_.找到NPC_;
            }
            恢复上一个值(人物);
            地图_.海岛仓库.一键存药(人物, out var 库存);
            var 购买设置 = 人物.购买设置;
            var 金币商城购买的物品 = new List<物品及数量_>();
            var 元宝商城购买的物品 = new List<物品及数量_>();
            var 商人购买的物品 = new List<物品及数量_>();
            var 仓库取的 = new List<物品及数量_>();

            foreach (var 值 in 购买设置.内容)
            {
                var 名称 = 值.Key;
                var 数量 = 值.Value;
                if (名称 == "治疗药水")
                {
                    仓库取的.Add(new 物品及数量_(名称, 数量));
                }
                else if (是可以从商人购买的物品(名称))
                {
                    商人购买的物品.Add(new 物品及数量_(名称, 数量));
                }
                else if (是可以从金币商城购买的物品(名称))
                {
                    金币商城购买的物品.Add(new 物品及数量_(名称, 数量));
                }
                else if (是可以从元宝商城购买的物品(名称))
                {
                    元宝商城购买的物品.Add(new 物品及数量_(名称, 数量));
                }
                else
                {
                    人物.输出(名称 + " 不支持购买");
                }
            }
            人物.输出("开始整理包裹");

            人物.包裹.整理包裹(true);
            var 现在空格数 = 人物.包裹.获取物品数量(_物品_.空包裹_);

            if (仓库取的.Count > 0)
            {
                var 现有数 = 人物.包裹.获取物品数量(_物品_.治疗药水_);
                var 需要的 = 仓库取的[0];
                if (需要的.数量 > 现有数)
                {
                    物品及数量_ 仓库取 = new 物品及数量_(需要的.名称, Math.Min(现在空格数, 需要的.数量 - 现有数));
                    地图_.海岛仓库.一键取药(人物, 仓库取.数量, out 库存);
                    现在空格数 = 现在空格数 - 仓库取.数量;
                }
            }

            if (元宝商城购买的物品.Count > 0)
            {
                var 元宝商城购买 = new List<物品及数量_>();
                foreach (var a in 元宝商城购买的物品)
                {
                    if (a.名称 == "金条")
                    {
                        var 现有数 = 人物.包裹.获取物品数量(_物品_.金条_);
                        if (a.数量 > 现有数)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                            元宝商城购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                    else if (a.名称 == "金砖")
                    {
                        var 现有数 = 人物.包裹.获取物品数量(_物品_.金砖_);
                        if (a.数量 > 现有数)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                            元宝商城购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                }
                if (元宝商城购买.Count > 0)
                {
                    商城_.购买元宝商城物品(人物, 元宝商城购买);
                    if (金币商城购买的物品.Count == 0) 商城_.关闭商城(人物);
                }
            }

            if (金币商城购买的物品.Count > 0)
            {
                var 第一页购买 = new List<物品及数量_>();
                var 第二页购买 = new List<物品及数量_>();

                foreach (var a in 金币商城购买的物品)
                {
                    if (a.名称 == "回城石")
                    {
                        var 现有数 = 人物.包裹.获取物品数量(_物品_.回城石_);
                        if (a.数量 > 现有数)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                            第一页购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                    else if (a.名称 == "随机神石")
                    {
                        var 现有数 = 人物.随机次数 > 20 ? 人物.包裹.获取物品数量(_物品_.随机神石_) : 0;
                        if (a.数量 > 现有数)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                            第一页购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                    else if (a.名称 == "冰泉圣水")
                    {
                        var 现有数 = 人物.冰泉次数 > 1 ? 人物.包裹.获取物品数量(_物品_.冰泉圣水_) : 0;
                        if (a.数量 > 现有数)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                            第一页购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                    else if (a.名称 == "道尊神符")
                    {
                        var 现有数 = 人物.道符次数 > 2000 ? 人物.包裹.获取物品数量(_物品_.道符_) : 0;
                        if (a.数量 > 现有数)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                            第一页购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                    else if (a.名称 == "道尊红毒")
                    {
                        int 现有数 = 0;
                        if (人物.技能.可以诅咒)
                        {
                            现有数 = 人物.红毒次数 > 800 ? 人物.包裹.获取物品数量(_物品_.雌人_) : 0;
                            if (a.数量 > 现有数)
                            {
                                var 商城买 = new 物品及数量_("雌偶", Math.Min(现在空格数, a.数量 - 现有数));
                                第二页购买.Add(商城买);
                                现在空格数 = 现在空格数 - 商城买.数量;
                            }
                        }
                        else
                        {
                            现有数 = 人物.红毒次数 > 800 ? 人物.包裹.获取物品数量(_物品_.红毒_) : 0;
                            if (a.数量 > 现有数)
                            {
                                var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                                第二页购买.Add(商城买);
                                现在空格数 = 现在空格数 - 商城买.数量;
                            }
                        }
                    }
                    else if (a.名称 == "道尊绿毒")
                    {
                        int 现有数;
                        if (人物.技能.可以诅咒)
                        {
                            现有数 = 人物.绿毒次数 > 800 ? 人物.包裹.获取物品数量(_物品_.雄人_) : 0;
                            if (a.数量 > 现有数)
                            {
                                var 商城买 = new 物品及数量_("雄偶", Math.Min(现在空格数, a.数量 - 现有数));
                                第二页购买.Add(商城买);
                                现在空格数 = 现在空格数 - 商城买.数量;
                            }
                        }
                        else
                        {
                            现有数 = 人物.绿毒次数 > 800 ? 人物.包裹.获取物品数量(_物品_.绿毒_) : 0;
                            if (a.数量 > 现有数)
                            {
                                var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有数));
                                第二页购买.Add(商城买);
                                现在空格数 = 现在空格数 - 商城买.数量;
                            }
                        }
                    }
                }
                if (第一页购买.Count > 0)
                {
                    商城_.购买第一页物品(人物, 第一页购买);
                    if (第二页购买.Count == 0) 商城_.关闭商城(人物);
                }
                if (第二页购买.Count > 0)
                {
                    商城_.购买第二页物品(人物, 第二页购买);
                    商城_.关闭商城(人物);
                }
            }
            人物.输出("购买完成");

            if (商人购买的物品.Count > 0)
            {
                var 商人购买 = new List<物品及数量_>();
                foreach (var a in 商人购买的物品)
                {
                    if (a.名称 == "特级金创药包")
                    {
                        var 现有金创药包数 = 人物.包裹.获取物品数量(_物品_.特级金创药包_);
                        if (现有金创药包数 < a.数量)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有金创药包数));
                            商人购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                    else if (a.名称 == "特级魔法药包")
                    {
                        var 现有魔法药包数 = 人物.包裹.获取物品数量(_物品_.特级魔法药包_);
                        if (现有魔法药包数 < a.数量)
                        {
                            var 商城买 = new 物品及数量_(a.名称, Math.Min(现在空格数, a.数量 - 现有魔法药包数));
                            商人购买.Add(商城买);
                            现在空格数 = 现在空格数 - 商城买.数量;
                        }
                    }
                }
                if (商人购买.Count > 0)
                {
                    地图_.海岛流浪商人.购买(人物, 商人购买);
                }
            }
            人物.需要补充 = false;
            人物.当前空包裹数量 = 现在空格数;
            return 人物.预存的任务;
        }

        public static 任务名_ 判断游戏状态(挂机人物_ 人物)
        {
            if (其他_.循环判断(() => UI_.查找996登录窗口().X != -1, 2))
            {
                // 如果是初始登陆 窗口就 登陆游戏
                return 操作_.登陆游戏(人物, 1);
            }
            // 如果 有游戏公告 就登陆
            var 找到登录公告 = UI_.查找游戏登陆公告(2);
            if (找到登录公告)
            {
                var 任务 = 从游戏公告登陆(人物);
                return 任务 != 任务名_.无_ ? 任务 : 任务名_.重启模拟器_;
            }

            var 进入游戏 = 其他_.循环判断(() => UI_.找到进入游戏按钮().X != -1, 2);
            if (进入游戏)
            {
                var 任务 = 从进入游戏登陆(人物);
                return 任务 != 任务名_.无_ ? 任务 : 任务名_.重启模拟器_;
            }
            Point 开始游戏按钮 = new Point(-1, -1);
            if (其他_.循环判断(() =>
            {
                开始游戏按钮 = UI_.找到确定登陆按钮();
                return 开始游戏按钮.X != -1;
            }, 2))
            {
                // 判断人物名称及职业登信息后 登陆
                return 判断人物及职业等级(人物);
            }
            return 操作_.设置初始值(人物);
        }

        public static 任务名_ 启动游戏(挂机人物_ 人物)
        {
            var 是否启动了 = 其他_.循环判断(() =>
            {
                return UI_.查找游戏标签图标().X != -1;
            }, 10, 500);

            人物.输出("游戏已启动: " + 是否启动了.ToString());

            if (是否启动了)
            {
                return 任务名_.判断游戏状态_;
            }

            Point p = new Point(-1, -1);
            if (其他_.循环判断(() =>
            {
                p = UI_.找到游戏图标();
                return p.X != -1;
            }, 10, 500))
            {
                其他_.延迟(其他_.时长_1000);
                键鼠_.左键单击(p);
                人物.输出("点击了游戏图标");

                是否启动了 = 其他_.循环判断(() =>
                {
                    return UI_.查找游戏标签图标().X != -1;
                }, 40, 500);

                if (是否启动了)
                {
                    return 任务名_.登陆游戏_;
                }

                人物.输出("登陆超时");
                return 任务名_.重启模拟器_;
            }

            人物.输出("没找到游戏app");

            return 任务名_.重启模拟器_;
        }

        public static 任务名_ 登陆游戏(挂机人物_ 人物, int 检查次数 = 10)
        {
            var 循环次数 = 0;
            var 存储检查次数 = 检查次数;
            检查次数 = 5;
        _在看一次_:
            if (其他_.循环判断(() => UI_.查找996登录窗口().X != -1, 检查次数))
            {
                var p = 图像_.查找图片(Properties.Resources.协议同意对号, 441, 444, 457, 459);
                if (p.X == -1 || p.Y == -1)
                {
                    人物.输出("勾选同意协议");
                    键鼠_.左键单击(446, 449);
                    其他_.延迟(其他_.时长_1000);
                }
                人物.输出("点击确定登陆");
                键鼠_.左键单击(636, 527);
            }
            var 找到登录公告 = UI_.查找游戏登陆公告(检查次数);
            if (找到登录公告)
            {
                var 任务 = 从游戏公告登陆(人物);
                if (任务 != 任务名_.无_)
                {
                    return 任务;
                }
            }
            if (循环次数 < 2)
            {
                循环次数++;
                if (检查次数 < 存储检查次数) 检查次数++;
                人物.输出("在看一次");
                goto _在看一次_;
            }
            人物.输出("游戏登陆超时");
            return 任务名_.重启模拟器_;
        }

        public static 任务名_ 从游戏公告登陆(挂机人物_ 人物)
        {
            人物.输出("点击登陆公告");
            键鼠_.左键单击(762, 581);

            var 进入游戏 = 其他_.循环判断(() => UI_.找到进入游戏按钮().X != -1, 5);
            if (进入游戏)
            {
                return 从进入游戏登陆(人物);
            }
            return 任务名_.无_;
        }

        public static 任务名_ 从进入游戏登陆(挂机人物_ 人物)
        {
            人物.输出("点击进入游戏");
            键鼠_.左键单击(其他_.取中心(591, 489, 688, 516));

            Point 登陆开始按钮 = new Point(-1, -1);
            if (其他_.循环判断(() => UI_.找到确定登陆按钮().X != -1, 10))
            {
                return 判断人物及职业等级(人物); ;
            }
            return 任务名_.无_;
        }

        public static 任务名_ 判断人物及职业等级(挂机人物_ 人物)
        {
            if (人物.是左侧人物)
            {
                键鼠_.左键单击(380, 270);
                人物.输出("选择左侧人物");
                其他_.延迟(其他_.时长_1000);
            }
            else
            {
                键鼠_.左键单击(1012, 270);
                人物.输出("选择右侧人物");
                其他_.延迟(其他_.时长_1000);
            }
            if (人物.职业 == "")
            {
                if (人物.是左侧人物)
                {
                    人物.姓名 = UI_.识别左姓名();
                    人物.职业 = UI_.识别左职业();
                    人物.等级 = UI_.识别左等级();
                }
                else
                {
                    人物.姓名 = UI_.识别右姓名();
                    人物.职业 = UI_.识别右职业();
                    人物.等级 = UI_.识别右等级();
                }
            }
            人物.输出("姓名: " + 人物.姓名);
            人物.输出("职业: " + 人物.职业);
            人物.输出("等级: " + 人物.等级);
            其他_.延迟(其他_.时长_3000);
            return 小退后登陆(人物);
        }

        public static 任务名_ 小退后登陆(挂机人物_ 人物)
        {
            人物.输出("点击登陆");
            键鼠_.左键单击(634, 722);

            if (其他_.循环判断(() => UI_.找到游戏健康公告().X != -1, 10))
            {
                人物.输出("关闭游戏健康公告");
                键鼠_.左键单击(642, 643);

                if (其他_.循环判断(() => UI_.找到游戏健康公告().X == -1, 20))
                {
                    return 任务名_.初始设置_;
                }
                人物.输出("登陆失败");
                return 任务名_.重启模拟器_;
            }
            return 任务名_.判断游戏状态_;
        }

        private static void 关闭模拟器(挂机人物_ 人物)
        {
            if (人物.窗口句柄 != IntPtr.Zero)
            {
                人物.输出("关闭模拟器窗口");
                窗口_.关闭窗口(人物.窗口句柄);
                窗口_.GetWindowThreadProcessId(人物.窗口句柄, out var id);
                if (id != 0)
                {
                    人物.输出("结束窗口进程");
                    var 窗口进程 = Process.GetProcessById((int)id);
                    窗口进程.Kill();
                    其他_.延迟(其他_.时长_5000);
                }
            }
        }

        public static 任务名_ 重启模拟器(挂机人物_ 人物)
        {

            if (人物.雷达.来人监控线程.是否在运行 == true)
            {
                人物.雷达.来人监控线程.退出();
            }
            if (其他_.循环判断(() =>
            {
                关闭模拟器(人物);
                return true;
            }))
            {
                人物.模拟器已经启动 = false;
                人物.小退时间 = DateTime.Now;
                其他_.延迟(其他_.时长_1000);
                return 任务名_.启动模拟器_;
            }
            return 任务名_.无_;
        }
    }
}
